-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.xml
More file actions
1875 lines (1875 loc) · 199 KB
/
index.xml
File metadata and controls
1875 lines (1875 loc) · 199 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Graham's Blog</title><link>/blog/</link><description>Recent content on Graham's Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sat, 05 Apr 2025 00:00:00 +0000</lastBuildDate><atom:link href="/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>I'm sorry, Python, it's time to say 'goodbye'.</title><link>/blog/posts/2025/05_goodbye_python/goodbye/</link><pubDate>Sat, 05 Apr 2025 00:00:00 +0000</pubDate><guid>/blog/posts/2025/05_goodbye_python/goodbye/</guid><description><p>I have noticed something recently that I want to talk about. When I start new projects, I usually have an idea and implement it in Python. I used to say &ldquo;I love Python for prototyping&rdquo;, but even that has become less useful than starting with Go. Now, every time I try to do something in Python, all of the quirks of Python (and its slowness) cause me to switch to Go in the same working session. This has happened so many times, I just need to give up on my preference for Python.</p>
<h2 id="what-went-wrong">What went wrong</h2>
<p>In summary, two problems:</p>
<ol>
<li>It&rsquo;s slow and buggy</li>
<li>The developer feedback advantage <a class="link" href="https://gportal.link/blog/posts/2025/04_typescript_port_go/typescript_go/#why-improving-the-typescript-compiler-matters---a-lot" target="_blank" rel="noopener"
>that I love so much</a> is gone.</li>
</ol>
<p>Every simple task I want to do in Python gets derailed immediately. Web crawler? It&rsquo;s simply too slow. Data processor? The data type and validation features take too long. Multi-service healthcheck? works for one at a time, but then multiprocessing is so catastrophically bad in Python, it&rsquo;s easier to switch to Go.</p>
<p>Then there&rsquo;s the dev process. I am a fan of fast developer feedback, and Python always came out on top because of its interpreted nature. I could modify the code and immediately run it again. But I have noticed I end up spending more time re-running because of dumb typos and little errors that I don&rsquo;t see until the code block is executed in Python, so it&rsquo;s not an advantage anymore. Go is compiled and compiles <em>quickly</em>. It gives me instantaneous feedback when there are typos or when a function isn&rsquo;t returning the right data type.</p>
<p>Then, there&rsquo;s Docker&hellip; I use Docker a lot. How can installing and compiling code be faster for a Go Docker image than an interpreted Python image? I can&rsquo;t believe it, but it is.</p>
<p>Every major advantage of Python is gone. All except one &ndash; which I will talk about later.</p>
<h2 id="developer-experience">Developer Experience</h2>
<p>Let&rsquo;s list some problems with Python:</p>
<ul>
<li><strong>Getting started:</strong> When I prototype a project, Python starts with nothing. I have to pick the package manager&hellip; just requirements.txt? pipenv? poetry? uv? anacanda? Ok, just starting out, how about just a virtual environment?. Then what version of Python? The fragmentation of compatibility is quite exhausting.</li>
<li><strong>Validation:</strong> Sure, you can lint and add VSCode plugins to help validate your code before running, but it&rsquo;s another extra step that doesn&rsquo;t come for free with the Python interpreter.</li>
<li><strong>Packaging:</strong> How the heck should I &ldquo;package&rdquo; this for consumption? Docker makes the most sense, covering the most ground, and does solve a lot of my problems. But it requires WSL for Windows and an extra layer there. The build process and virtual env behavior for Docker is sometimes tricky to get working exactly right.</li>
<li><strong>resource usage:</strong> Python can be lean and simple when run natively as a script on a host. And in the past, a Python Docker image was only 50 MB as a minimum. But now the Python slim images are 200MB plus your package code, which usually doubles the size.</li>
</ul>
<p>Why does Go do it better?</p>
<ul>
<li><strong>Getting started:</strong> Go is a simple binary compiler and linter program that does everything out of the box. You can always use the latest Go binary, and it has guaranteed backwards compatibility.</li>
<li><strong>Validation:</strong> You can&rsquo;t run your program unless it passes compile checks and simple built-in static checks.</li>
<li><strong>Packaging:</strong> It produces an executable file, by default for your platform or easily and quickly for any target platform. All with blazing fast compile times.</li>
<li><strong>resource usage:</strong> You can put an executable in a Docker image if you want, a Docker image that is 1.5MB in size that does the same as the 500MB Python image.</li>
</ul>
<p>My jaw always drops when I switch my prototyped project from Go to Python because of these advantages. I constantly think &ldquo;I should have done this from the beginning&rdquo;.</p>
<h2 id="theres-just-one-problem">There&rsquo;s just one problem</h2>
<p>Python&rsquo;s ecosystem is robust. That&rsquo;s both good and bad. If you want to do something simple like JSONpath query, there&rsquo;s a robust library for that. Sure, it&rsquo;s going to add 100MB of dependencies to your project, but it&rsquo;s simple to add and works.</p>
<p>With Go, you can import libraries for many things. But I find they are usually not as robust and useful. Many times, it&rsquo;s better to do a scoped implementation of your own that works for your use case.</p>
<p>So this is still one area where Python comes out on top - if you need to use a certain library. But for me, this is rarely an issue.</p>
<h2 id="goodbye-python">Goodbye Python</h2>
<p>So, I will bid farewell to Python as my &ldquo;go-to&rdquo; project language in favor of Go. The Python runtime is an awesome technology, and the recent changes to the GIL should help Python be more performant. But it&rsquo;s not enough, it&rsquo;s simply too late. I&rsquo;m sorry, Python, our time is over. In my mind, Python is going the way of Java. I will still know it and use it because it&rsquo;s everywhere. But never again for my starter projects.</p>
<p>Because, there is a better way.</p></description></item><item><title>Why Microsoft's strategic choice to use Go for Typescript compiler matters</title><link>/blog/posts/2025/04_typescript_port_go/typescript_go/</link><pubDate>Thu, 13 Mar 2025 00:00:00 +0000</pubDate><guid>/blog/posts/2025/04_typescript_port_go/typescript_go/</guid><description><img src="https://gportal.link/blog" alt="Featured image of post Why Microsoft's strategic choice to use Go for Typescript compiler matters" /><p>Microsoft gave a surprise announcement recently: they are <a class="link" href="https://devblogs.microsoft.com/typescript/typescript-native-port/" target="_blank" rel="noopener"
>porting the typscript compiler to go</a>! This is exciting for many reasons but also surprising for many other reasons.</p>
<p>I&rsquo;ll address the central question right from the start - <em>Why go instead of other languages</em>? Because go easily allows them to do a <em>port</em> of typescript code vs a complete re-write. So, backwards compatibility and the timeline for release is much improved.</p>
<p>Using go makes sense to me: it&rsquo;s a fast, lightweight, proven language that has all the necessary type features needed for the job.</p>
<p>Now, in this article, I want to explain my thoughts on typescript and give some of my opinions on typescript in general.</p>
<h2 id="why-improving-the-typescript-compiler-matters---a-lot">Why improving the typescript compiler matters - a lot</h2>
<p>Nobody likes waiting.</p>
<p>I have always been hesitant to embrace typescript for my projects. I am fully aware of the benefits of using typescript, but it also has cons that need to be weighed. Many of my projects have very minimal and lightweight frontends. So much so, that I have often opted not to use any framework to build them and use vanilla javascript. Yes, that&rsquo;s right - vanilla javascript. For a very simple reason: I want my build process to be <strong>blazingly fast</strong>. I highly value and prioritize faster developer feedback in the form of fast compile times (one reason I love go!). For a small project, I think the value of fast feedback for changes outweighs the type safety benefits of typescript.</p>
<blockquote>
<p>The moment you include typescript, you need a framework, and your project suddenly balloons in size.</p>
</blockquote>
<p>If your project&rsquo;s goal is fast and minimal, typescript is at odds. It needs a typescript-compatible framework to be useful. Otherwise, you have to use the typescript compiler on its own and essentially build your framework around the compiler.</p>
<p>With this in mind, typescript compilation becomes an unfortunate bottleneck in the process. Compling typescript code to javascript increases build time significantly. So, if Microsoft is able to solve the problem, that solves half my issue with typescript.</p>
<h2 id="compile-time-challenges">Compile time challenges</h2>
<p>Let me put this into perspective with a real-world example. I maintain a <a class="link" href="https://github.com/gtsteffaniak/filebrowser" target="_blank" rel="noopener"
>fork</a> of the <a class="link" href="https://github.com/filebrowser/filebrowser" target="_blank" rel="noopener"
>filebrowser repository</a> that is vastly different and superior in many ways.</p>
<p>One of those ways: <strong>compile time</strong>.</p>
<p>When the original repo moved to Vue 3, they also converted most of the javascript to TypeScript- a choice I mostly avoided. This was intentional - because I noticed typscript significantly slowed down build times, I chose to keep the javascript versions mostly the same.</p>
<p>How much slower was it? Well, see for yourself:</p>
<h3 id="original-filebrowser-frontend-build-time-mostly-typescript">Original Filebrowser frontend build time (mostly typescript)</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">&gt; vue-tsc -p ./tsconfig.tsc.json --noEmit
</span></span><span class="line"><span class="cl">✓ 1140 modules transformed.
</span></span><span class="line"><span class="cl">✓ built in 19.12s
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="filebrowser-quantum-frontend-build-time-mostly-javascript">Filebrowser Quantum frontend build time (mostly javascript)</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">&gt; vite build
</span></span><span class="line"><span class="cl">✓ 188 modules transformed.
</span></span><span class="line"><span class="cl">✓ built in 1.83s
</span></span></code></pre></td></tr></table>
</div>
</div><p>That&rsquo;s a <strong>more than 10x improvement</strong>! This means I can make changes and test them much more quickly. Sure, there may be type-related errors in my code, but I will catch them while I debug. It&rsquo;s not ideal, but neither is using typescript.</p>
<p>I had the same problem using Svelte &ndash; I began to prefer Vue3 because I found my Svelte compile times (even without javascript) were quite slow, sometimes taking 10-15 seconds. Using vue3 with similar projects compiled quickly in under 1 second. I view compile time as a top priority, so it&rsquo;s unfortunate that I am limited to using certain frameworks because of it.</p>
<h2 id="typescript-is-currently-a-catch-22">Typescript is currently a catch-22</h2>
<p>The benefit of typescript is a bit of a catch-22. Its purpose is to ensure code quality, and it does that job well in many circumstances. If a project is maintained by a team, its &ldquo;pros&rdquo; can outweigh the &ldquo;cons&rdquo;.</p>
<p>However, for independent projects, I believe the cons outweigh the pros. Because, if using typescript slows down development, those type-related bugs could be found with playwright or javascript tests or during local debugging with the time you save waiting for compilation.</p>
<p>So, if typescript slows down developer feedback, it partly defeats the organic developer bug hunt. That&rsquo;s not always the case, but I hope I have made my point that sometimes it is.</p>
<h2 id="will-i-use-typescript-more-when-its-faster">Will I use typescript more when it&rsquo;s faster</h2>
<p>The final question is why I&rsquo;m personally excited for Typescript 7 with faster compile times. Once compile times have been reduced, it opens my options back up I can use more frameworks if the feedback loop is faster. I would much prefer a type-safe language that needs to be compiled first. My main reservation is the build time. And it looks like Microsoft is preparing to fix that!</p>
<p>So, yes &ndash; I can&rsquo;t wait to use Typescript 7.</p></description></item><item><title>AI is now a commodity</title><link>/blog/posts/2025/03_ai_commodity/commodity/</link><pubDate>Mon, 03 Mar 2025 00:00:00 +0000</pubDate><guid>/blog/posts/2025/03_ai_commodity/commodity/</guid><description><p>I believe 2025 is the year that AI has become a <a class="link" href="https://www.investopedia.com/terms/c/commodity.asp" target="_blank" rel="noopener"
>commodity</a> &ndash; particularly for LLMs. This shift plays a significant role in economics, whereas previously AI was married to specific actors like google, nvidia, or openAI and was a technological asset for each company.</p>
<h2 id="what-does-it-mean-to-be-a-commodity">What does it mean to be a commodity?</h2>
<p>A commodity is a common resource that can be traded with a known value. When I say AI is now a commodity, I am effectively saying that the big companies are losing their technology advantage. Instead of a company getting ahead financially because of having the &ldquo;Best AI&rdquo;, instead companies get ahead by making AI as cheap as possible.</p>
<blockquote>
<p>In a simple terms, AI is no longer about having a superior technology but instead about providing value and efficiency.</p>
</blockquote>
<p>We have seen the progress in AI models converge to a &ldquo;good enough&rdquo; output from every player. Because new advancements give very minimal advantage and sometimes come at a cost, products like o3-mini, deepseek distilled, grok-3 mini varients, have emerged offering better economic value.</p>
<p>It&rsquo;s a process known as <code>commoditization</code>, which according to investopedia:</p>
<blockquote>
<p>[Commoditization] removes the individual, unique characteristics, and brand identity of the product so that it becomes interchangeable with other products of the same type. Making commodities interchangeable allows competition with a basis of price only and not on different characteristics.</p>
</blockquote>
<h2 id="what-does-that-mean-for-ai-advancements">What does that mean for AI advancements?</h2>
<p>AI will still have marginal advancements when it comes to logic and reasoning. The results of the bigger models will get better, but its not0 going to be a driving factor for AI.</p>
<p>Companies will see the benefit of using AI ways that wasn&rsquo;t economical before. Ultimately, AI will see a bit of a plataue in performance benchmarks.</p>
<h2 id="what-is-the-impact-of-this-for-companies">What is the impact of this for companies?</h2>
<p>Most companies will continue to operate as they do now: offering AI features to customers as an incentive to use their product.</p>
<p>Winners:</p>
<ul>
<li>Companies such as OpenAI will continue to see growth because their models are still the go-to and used by many customers, they will rely on models that are cheaper to operate and provide higher profits as a result.</li>
<li>Companies such as Facebook, Google, Microsoft will see higher profits as well. They will continue to invest in cost-optimized solutions that can benefit their bottom line while still providing AI value to customers.</li>
<li>new AI hardware players such as AMD, Intel, and Apple will have more control and power over their technology because AI can be applied generally to more hardware configurations.</li>
</ul>
<p>Losers:</p>
<ul>
<li>Companies such as Nvidia will see the biggest hit from the commoditization of AI, because their products are not the only path to AI. AI models will no longer rely on propreitary technology from nvidia.</li>
</ul>
<h2 id="when-will-full-commoditization-occur">When will full commoditization occur?</h2>
<p>The transition to a fully commodized AI world will take time and depends on 3 factors:</p>
<ol>
<li>AI models will fully shift to &ldquo;mini&rdquo; variants and companies will use distilled versions for more things.</li>
<li>Companies will begin purchasing alternative hardware that is optimized for inferencing tasks on these mini models, saving cost over time.</li>
<li>AI sdk&rsquo;s will begin supporting these new models for user-end customers as well as large companies.</li>
</ol>
<p>I expect the vast majority of this to happen by the beginning of 2026.</p>
<h2 id="is-commoditization-good">Is commoditization good?</h2>
<p>In general, commoditization is a good thing because it moves the product category to a market that is free.</p>
<p>Commodities open up the playing field for more competition, which benefits the customers on a cost basis.</p>
<p>The biggest disadvantage is that performance advancements are no longer the most important thing, which can slow down innovation in that respect.</p>
<h2 id="bottom-line">Bottom line</h2>
<p>All popular technology products become a commodity eventually. The personal compute, the mobile phone, etc. AI is no exception. and particularly LLM&rsquo;s have needed this transition quite badly &ndash; it has scaled faster than infrastructure can keep up.</p>
<p>It has been very interesting to watch this process, because its been extremely accelerated for AI compared to many past products.</p>
<p>Hopefully we can see a graceful transition and the shift in economics doesn&rsquo;t cause a shock &ndash; or crash.</p></description></item><item><title>Thank God for Deepseek</title><link>/blog/posts/2025/02_deepseek/deepseek/</link><pubDate>Thu, 30 Jan 2025 00:00:00 +0000</pubDate><guid>/blog/posts/2025/02_deepseek/deepseek/</guid><description><p>Well, it took many years to come to this but the <strong>biggest advancement</strong> in LLM&rsquo;s is finally here! Make no mistake - deepseek is the most significant development in AI since chatGPT&rsquo;s introduction in 2022.</p>
<p>As I mentioned before, AI is way more than just LLM&rsquo;s and I want to see more. However, LLM&rsquo;s are the driving force of AI investment, hardware development, and global impact. So, when a seismic shift in LLM technology happens, that&rsquo;s a huge thing.</p>
<blockquote>
<p>Disclosure: The words in this post were not AI-generated or altered in any meaningful way. Spell check and other tools were used, but all content and phrases are my own creations.</p>
</blockquote>
<h2 id="why-is-deepseek-so-hyped">Why is deepseek so hyped?</h2>
<p>There are so many reasons deepseek is a huge breakthrough, but let me order them in my top 5:</p>
<ol>
<li><strong>It&rsquo;s open source</strong>
<ul>
<li>This is Unlike Closed source &ldquo;openAI&rdquo; models like ChatGPT.</li>
</ul>
</li>
<li><strong>It&rsquo;s novel</strong>
<ul>
<li>It uses a new reduction technique that solves a lot of challenges with LLMs &ndash; and does so while still topping the benchmarks on performance.</li>
</ul>
</li>
<li><strong>You can run it yourself</strong>
<ul>
<li>Not just because the code and models are open source, but also because of the reduction technique used, you can do it on regular hardware, with as little as 9GB of memory.</li>
</ul>
</li>
<li><strong>It reduces hardware needs</strong>
<ul>
<li>This is not just a benefit for a hobbyist, this resets the insane power requirements of LLMs back down to reasonable levels.</li>
</ul>
</li>
<li><strong>It comes just in time</strong>
<ul>
<li>We need this as humanity. Otherwise, Nvidia will assume full control with a wide range of propriety AI tech that requires everyone to buy a dizzying amount of hardware. Now, not only do you need to buy less, but you can run the model on alternative hardware &ndash; such as Apple and NPUs created by other hardware companies like AMD, Qualcomm, and intel.</li>
</ul>
</li>
</ol>
<h2 id="comparing-with-openai-and-gemini">Comparing with OpenAI and Gemini</h2>
<p>Let me just show one simple example. I want to test <code>censorship</code>, <code>comprehension</code>, <code>speed</code>, and <code>relevance</code> between them, with that in mind.</p>
<p>First, a simple question :</p>
<blockquote>
<p>What is the biggest engineering innovation of 2024 involving math and why?</p>
</blockquote>
<p>followed by</p>
<blockquote>
<p>Give me a technical analysis of the mathematical algorithms related to the quantum computing innovation.</p>
</blockquote>
<p><strong>Gemini</strong>:</p>
<ol>
<li>incredibly fast, gave 3 general topics: AI, quantum computing, and simulation&hellip; and a summary saying <code>It's still early in 2024</code> oops.</li>
<li>incredibly fast, gave 7 examples and their actual merits, but did not demonstrate much actual math.</li>
</ol>
<p><strong>OpenAi</strong>:</p>
<ol>
<li>a little slower, gave a short mention of quantum computing.</li>
<li>a little slower, gave a detailed response with actual algorithms and their explanations! nice!</li>
</ol>
<p><strong>deepseek</strong>:</p>
<ol>
<li>gave a similar response to Gemini.</li>
<li>gave a very similar response as Gemini.</li>
</ol>
<p>Now, one more that leans on censorship.</p>
<blockquote>
<p>Which countries have the most nuclear warheads and which ones are the biggest threat because of that?</p>
</blockquote>
<p>with the followup</p>
<blockquote>
<p>Should I be concerned living in the West if Asian countries have nuclear weapons?</p>
</blockquote>
<p><strong>Gemini</strong>:</p>
<ol>
<li>Quick response, but very poor quality answer. It gave no specifics including a list. It mentioned Russia and the US had a certain number of nuclear weapons but steered away from describing any specific threats or mentioning any countries in a negative way.</li>
<li>As expected, Gemini censorship training went into full force in this response. Not only declining to specify any threat, the second half simply gave the &ldquo;balanced view&rdquo; lecturing the questioner about how they shouldn&rsquo;t generalize Asian countries and that the question was coming from a misguided perspective.</li>
</ol>
<p><strong>OpenAi</strong>:</p>
<ol>
<li>a little slower, listed countries with nukes and their count. Cross-referencing the internet the counts were close but a little off. The threat meter showed Russia and China at the top and the US at the bottom but didn&rsquo;t give much explanation for the ratings.</li>
<li>quite slow, says the threat is generally highly improbable without naming any countries specifically. Not too detailed or helpful.</li>
</ol>
<p><strong>deepseek</strong>:</p>
<ol>
<li>Probably the best answer of the 3, giving a detailed list of all countries and the count. Also gives a &ldquo;threat level&rdquo; rating for each country! Russia, Pakistan, and North Korea were marked &ldquo;high threat&rdquo; and the US, and Israel were marked &ldquo;moderate threat&rdquo;. Very good response.</li>
<li>A little slow, but faster than OpenAI. Amazing answer. addresses the concern, doesn&rsquo;t lecture, and gives a ton of useful information.</li>
</ol>
<h3 id="conclusion">conclusion</h3>
<p>I still really enjoy OpenAI&rsquo;s style, but deepseek is better from my experience and these tests I believe show this quite well. I plan to use deepseek instead of openAI because of this experience.</p>
<h2 id="where-should-we-go-from-here">Where should we go from here?</h2>
<p>Use deepseek! Try it on your Macbook, it&rsquo;s very cool and useful. I am sure the differences with deepseek are going to revolutionize the industry and I can&rsquo;t wait to see it happen.</p></description></item><item><title>2025 New Years Wishlist</title><link>/blog/posts/2025/01_wishlist/wishlist/</link><pubDate>Fri, 03 Jan 2025 00:00:00 +0000</pubDate><guid>/blog/posts/2025/01_wishlist/wishlist/</guid><description><img src="https://gportal.link/blog" alt="Featured image of post 2025 New Years Wishlist" /><p>Welcome to the 2025 New Year! I want to reflect and provide an opinionated wishlist for the next year based on trends. There are many exciting things happening and I would like to see how these thoughts age (by the time I read this in a year).</p>
<p>Disclosure: The words in this post were not AI-generated or altered in any meaningful way. Spell check and other tools were used, but all content and phrases are my own creation.</p>
<h2 id="i-hope-ai-evolves">I hope AI evolves</h2>
<p>I have been rooting for Nvidia and AI in general for at least the past 15 years. I was an early investor in Nvidia specifically because I knew the company was on to something, whether in AI or the general graphics space. I bought (and sold) shares at prices that would make you cry if you knew how much they would be worth today.</p>
<p>However, I am disappointed in the state of AI. &ldquo;AI&rdquo; is a very broad term and the most popular forms of AI that people think of are <code>image generation</code> via stable diffusion and <code>chatbot</code> AI via large language models. Image generation has been a useful newcomer to the AI arsenal we have, but it didn&rsquo;t solve a problem we couldn&rsquo;t solve before. Image generation allows us to solve problems <em>faster</em>, but not always <em>better</em>. That and it didn&rsquo;t bring anything truly new to the table. We have always been able to make images with Photoshop or other tools &ndash; if we have the skill or money to pay someone with the skill. However, LLM&rsquo;s like Chatgpt brought something entirely new and innovative. We never could generate coherent responses in natural language like this before. It&rsquo;s amazing for certain applications that depend on text-based documents &ndash; such as programming, drafting documents, summarizing documents, and many other workflows.</p>
<p>There are a few problems with LLMs:</p>
<ol>
<li>They are being too broadly used and touted as the ultimate form of AI. Every little action that can process text is being run through an LLM and many times is totally worthless. Do we really need to reformat the text every time I right click? Does every google search really need an AI summary? It&rsquo;s AI overload for users and extremely expensive and taxing on our power grid and cloud computing infra, totally wiping out our energy goals.</li>
<li>It leads to misinformation, which makes us dumber as a society. Sure, there have been major improvements to the logic and problem-solving performance of some of these models, but that doesn&rsquo;t change the performance of the model for fact-gathering. It can still rip bogus information from its sources such as blogs. This was indeed a problem before LLM&rsquo;s, you could always visit a blog on the internet&hellip; but you had a source before that you could judge for its trustworthiness. Now, an LLM regurgitates nonsense from a blog post somewhere deep on the internet and mixes that info with statements from reputable sources like the Department of Health&hellip; and in seconds you have a professional-sounding response at the top of Google that is total BS.</li>
<li>Finally - AI is so much more than LLM&rsquo;s! AI can use way more than text-based input. Consider for robotics, all the sensors that input data which can be run through AI models to see patterns and perform actions. Consider the amazing advancements possible in medicine and the medical field if an AI model had both the text input of all of your medical records the visual input of your MRI scans AND the sensor input of medical devices. So much could be accomplished that provides hope and help to humanity. Consider culinary creations possible by using dietary requirements, meal preferences, and the ingredients to create meal plans based on your needs. All of this is being ignored because we have a text prompt that sounds like a really smart person at all times.</li>
</ol>
<p>So, while these recent forms of AI are cool and useful. It&rsquo;s not nearly with its overly exuberant hype, nor the trillions of dollars of investment and exponentially exploding energy usage. It feels dystopian how reliant we are on such a flawed resource. It feels wrong how lazy we are becoming because these resources are so much easier than studying and fact-finding ourselves. Lastly, it&rsquo;s also too soon since we don&rsquo;t have an efficient way to use it. I really hope hardware innovation comes soon to cap energy usage.</p>
<h2 id="i-hope-the-world-economy-remains-stable">I hope the world economy remains stable</h2>
<p>There are a ton of geopolitical and issues facing the global economy that could have downstream effects that could cause some morally unthinkable events. I truly believe the old saying <a class="link" href="https://en.wikipedia.org/wiki/It%27s_the_economy,_stupid" target="_blank" rel="noopener"
>it&rsquo;s the economy, stupid</a> is true. If people are more secure financially and their economic umbrella is secure, then they won&rsquo;t resort to desperate actions. I feel no need to go into specifics because there are many examples you can associate this with. Leaders of the world make decisions based on the needs of their people, for political purposes, and their own benefits now and in the future.</p>
<p>Here are a few main points I want to highlight:</p>
<ul>
<li><strong>There&rsquo;s lots of change happening</strong>: Changes that are both good and bad. Having a stable canvas for these changes are essential.</li>
<li><strong>Extreme changes in the supply chain promote extreme responses</strong>: When we make massive changes to the supply chain for whatever reason, we inevitably make &ldquo;winners&rdquo; and &ldquo;losers&rdquo;. Those on the losing end have a strong and impedient interest to retaliate. Doing so can make everyone a &ldquo;loser&rdquo; in some respect.</li>
<li><strong>Everyone should have an opportunity to succeed</strong>: Any global or national event that disproportionally affects a certain group of people will cause suffering. Even positive changes can have powerful negative consequences, so I believe making big changes slowly over time is critical to stability. This slowness for massive changes enables people to react and adapt over time without causing a huge disruption.</li>
</ul>
<p>No matter how our world evolves, I hope it evolves at a pace that doesn&rsquo;t jeopardize our livelihood as a society. I hope our global economy is free and available to everyone. The more that can be included in our global economy, the more success we will all share.</p>
<h2 id="i-hope-we-can-remember-what-it-means-to-be-human">I hope we can remember what it means to be human</h2>
<p>Yes&hellip; It&rsquo;s 2025, 5 years since Covid happened and I think it&rsquo;s still worth talking about. The lockdowns are long gone, but we are still more isolated in many ways.</p>
<p>There were many good things &ndash; I truly value some of the positive changes from COVID-19:</p>
<ol>
<li>It kicked off a remote work frenzy that I have enjoyed.</li>
<li>It shifted so many people&rsquo;s future plans &ndash; being forced to quit dead-end jobs and explore new paths that they didn&rsquo;t have time to think about before.</li>
<li>It created a world that was more creative and gave us a break from the norm.</li>
</ol>
<p>Then, obviously, it had severe negative consequences. Many of which we are still battling. I truly believe COVID permanently altered the way society behaves to this day. We became less patient and unable to make concessions to our friends, family, and neighbors. It created a society less &ldquo;tolerating&rdquo; of things that cause us to be uncomfortable.</p>
<p>Families have been altered and friendships have changed. Support systems have been destroyed and many are not looking back. I believe this is true for everyone, but it is especially true for <a class="link" href="https://link.springer.com/article/10.1007/s00787-023-02206-8" target="_blank" rel="noopener"
>children and adults</a>:</p>
<blockquote>
<p>The COVID-19 pandemic and associated containment measures have massively changed the daily lives of billions of children and adolescents worldwide.</p>
</blockquote>
<p>It will probably be another decade before we can truly know the social ripple effects of covid, but its clear it has had massive implications for children.</p>
<p>I think for my age range it caused people to skip straight to a &ldquo;home life&rdquo; rather than exploring the world or moving to exciting locations for a time you usually do in your 20s.</p>
<p>I think &ldquo;home life&rdquo; can be anti-social in many ways. Going out can be uncomfortable. It can mean taking risks and doing things that are new and possibly regretful. Staying home is easy. It&rsquo;s hard for me to distinguish if this is a natural progression from 20 to 30 years of age, or if something related to covid did happen. But I think it&rsquo;s mostly a net negative. If we don&rsquo;t spend time as much around people we may not agree with or hang out with, we lose those social skills and how to participate in society in a &ldquo;human&rdquo; and reasonable way.</p>
<h2 id="i-want-to-create-and-contribute-more">I want to create and contribute more</h2>
<p>Like many, the ultimate goal would be to have financial and personal freedom. This is often unrealistic and sometimes not a proper use of time. However, I enjoy creating products, services, and things that work like I imagine before they become reality. I enjoy that creative pursuit. I have always wanted to master a creative craft in tech like image editing, 3d modeling, and video editing, video game creation, but I feel too far behind the curve on most of the technologies needed to master them. So, perhaps I can lightly incorporate some of these ideals into what I believe I have done a pretty decent job at mastering: cicd, cloud services, and scalable applications.</p>
<p>I would love to have some unified portfolio where all my applications borrow from each other, dip into the domain of creative arts, and also provide a valuable contribution to society. In 2025 I want to see that vision through, create truly useful and unique products with the talents that I have and expand into those creative domains&hellip; if only slightly.</p>
<p>If others found the products useful or worthwhile, I wouldn&rsquo;t turn down donations. Imagine, if I had full bandwidth to work on my own products, I could accomplish so much. For now, it&rsquo;s only a dream, but 2025 I plan to work towards that dream and maybe I could get lucky and see a financial incentive &ndash; or the advantage of having a contribution that brings others some use. Either way, I would like that to happen some day.</p></description></item><item><title>Migration experience for vue 2 to vue 3</title><link>/blog/posts/2024/vue_migration/vue_migrtation/</link><pubDate>Sat, 12 Oct 2024 00:00:00 +0000</pubDate><guid>/blog/posts/2024/vue_migration/vue_migrtation/</guid><description><img src="https://gportal.link/blog" alt="Featured image of post Migration experience for vue 2 to vue 3" /><p>Disclosure: The words in this post were not AI-generated or altered in any meaningful way. Spell check and other tools were used, but all content and phrases are my own creation.</p>
<p>I wanted to write about the experience of migrating the <a class="link" href="https://github.com/gtsteffaniak/filebrowser" target="_blank" rel="noopener"
>FileBrowser Quantum</a> from vue 2 to vue 3 because it took a lot of strategy to do smoothly. I enjoy working with Vue but the experience of moving between versions was quite bad.</p>
<p>The <a class="link" href="https://github.com/filebrowser/filebrowser/pull/2689" target="_blank" rel="noopener"
>original filebrowser application</a> took almost 1 year to complete the migration and I forked the repo in the middle of the migration before it was finished. In hindsight, I am still glad for this, because it gave me valuable experience in migrating a large Vue application and the opportunity to think about components that were not needed.</p>
<p>I <a class="link" href="https://gportal.link/blog/posts/2023/october/dependency-on-dependencies/" target="_blank" rel="noopener"
>wrote about</a> my ire for unnecessary dependencies which node modules are a big part of. I later <a class="link" href="https://gportal.link/blog/posts/2023/december/process_simplify_modules/" target="_blank" rel="noopener"
>wrote about</a> some things I did to simplify the application so migration could be more easily done. This is the final post I will make about my experience finishing it.</p>
<h2 id="why-it-took-so-long">Why it took so long</h2>
<p>I was mostly to blame for the delay. Sure, it took me less time than the original repo, which had one <a class="link" href="https://github.com/filebrowser/filebrowser/pull/2689" target="_blank" rel="noopener"
>primary migration PR</a> which took 8 months to merge! My problem was that I kicked the can down the road and said I would handle it later after a couple of different attempts I made in a day were insufficient. So, I left it alone, until I realized I lost interest in developing the repo because I knew I needed to migrate and that was always in the back of my mind.</p>
<p>So, in <a class="link" href="https://github.com/gtsteffaniak/filebrowser/releases/tag/v0.2.6" target="_blank" rel="noopener"
>version v0.2.6</a> I finally completed the migration!</p>
<h2 id="how-i-handled-the-migration">How I handled the migration</h2>
<p>In my previous posts, I mentioned I would choose a <em>reduction first</em> strategy. I removed many unnecessary dependencies by replacing them with a few lines of simple code that accomplished the same thing:</p>
<p>First, in <a class="link" href="https://github.com/gtsteffaniak/filebrowser/releases/tag/v0.2.6" target="_blank" rel="noopener"
>version v0.2.6</a>, I started preparing for the migration:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">In prep for vue3 migration, npm modules were removed:
</span></span><span class="line"><span class="cl">js-base64
</span></span><span class="line"><span class="cl">pretty-bytes
</span></span><span class="line"><span class="cl">whatwg-fetch
</span></span><span class="line"><span class="cl">lodash.throttle
</span></span><span class="line"><span class="cl">lodash.clonedeep
</span></span></code></pre></td></tr></table>
</div>
</div><p>Then, in version <code>v0.2.6</code> I finished the migration:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">removed npm modules:
</span></span><span class="line"><span class="cl">vuex
</span></span><span class="line"><span class="cl">noty
</span></span><span class="line"><span class="cl">moment
</span></span><span class="line"><span class="cl">vue-simple-progress
</span></span></code></pre></td></tr></table>
</div>
</div><p>In total there were 9 different dependencies were removed. All of which would have complicated the migration if I chose to keep them around. It also helped reduce bundle size, making the site just a little bit quicker.</p>
<p>Ultimately, the Vue 3 challenges were quite minimal (besides dependencies). There were a few state-related changes and the switch to vite was the most significant. However, the biggest hurdle (unrelated to vue itself) was that dependencies <strong>had their own dependencies</strong> that required certain vue versions. Which is, in my opinion, the worst part of a tech stack&hellip; untangling the web of dependencies.</p>
<h2 id="after-the-migration">After the migration</h2>
<p>Once the migration was complete, I was able to make a lot of great changes very quickly. It&rsquo;s very clear that having a site held back by old versions slowed down my interest in the site and my morale. I learned a lot about what to do and not to do, but overall I feel pretty happy with how it went.</p>
<p>Take a look at how much faster <a class="link" href="https://github.com/gtsteffaniak/filebrowser/releases" target="_blank" rel="noopener"
>The releases</a> have been since the migration:</p>
<p>2024 FileBrowser Quantum Releases Summarized:</p>
<table>
<thead>
<tr>
<th>date</th>
<th>version</th>
<th>change</th>
</tr>
</thead>
<tbody>
<tr>
<td>Feb 9th</td>
<td>v0.2.4</td>
<td>prepped for migration, some sharing features</td>
</tr>
<tr>
<td>June 12th</td>
<td>v0.2.5</td>
<td>a minor bugfix&hellip;</td>
</tr>
<tr>
<td>July 30th</td>
<td>v0.2.6</td>
<td>The migration was completed! Yay!</td>
</tr>
<tr>
<td>Aug 3rd </td>
<td>v0.2.7</td>
<td>behavior changes, bugfixes</td>
</tr>
<tr>
<td>Aug 24th</td>
<td>v0.2.8</td>
<td>LOTS</td>
</tr>
<tr>
<td>Sept 17th</td>
<td>v0.2.9</td>
<td>LOTS</td>
</tr>
<tr>
<td>Oct 7th </td>
<td>v0.2.10</td>
<td>Folder size feature, bugfixes</td>
</tr>
</tbody>
</table>
<p>You can see the pace <strong>clearly</strong> picked up! In the first half of 2024, I didn&rsquo;t make any significant changes. Once the migration was completed, I was able to work on a lot more things.</p>
<p>I am glad its all done and looking forward to making some of the more meaningful changes that I have wanted to do for a while.</p></description></item><item><title>March 2024 Update</title><link>/blog/posts/2024/march_update/march_update/</link><pubDate>Thu, 14 Mar 2024 00:00:00 +0000</pubDate><guid>/blog/posts/2024/march_update/march_update/</guid><description><img src="https://gportal.link/blog" alt="Featured image of post March 2024 Update" /><p>Disclosure: The words in this post were not AI-generated or altered in any meaningful way. Spell check and other tools were used, but all content and phrases are my own creation.</p>
<p>Hi to anyone lurking.</p>
<h2 id="before-and-after-blog-change">Before and after blog change</h2>
<p>I don&rsquo;t post that much, but have been working on the blog in a way that I think makes it a lot better.</p>
<p>Most notably, its not using a totally different generator. It uses <a class="link" href="https://gohugo.io/" target="_blank" rel="noopener"
>hugo</a>.</p>
<p>So now, the website currently looks like this:
<img src="https://github.com/gtsteffaniak/blog/assets/42989099/a02cae0b-4d73-465a-a501-636c17f69309"
loading="lazy"
alt="image"
></p>
<p>vs the original:
<img src="https://github.com/gtsteffaniak/blog/assets/42989099/9fa47b6f-6fb3-439c-a255-2a718e918d3a"
loading="lazy"
alt="image"
></p>
<h2 id="quick-thoughts-on-why-the-change">Quick thoughts on why the change</h2>
<p>I think it looks better, but need a few tweaks still. I am enjoying the hugo html templating as well, but a little disappointed to find out the hugo templating cutom functioning everywhere out of necessity. I wish to keep the old site around as well, with maybe /old/ path, because I can&rsquo;t easily do the css art styles like I could before, so for now I have those couple posts hidden. Though I think I will try to find a way to add the custom js and back for certain articles.</p>
<p>Svelte was more enjoyable to develop with when it comes to the svelte files. But the downsides were apparent: updating npm , creating my own javascript that was subpar to actual generated html. I am happy with the switch and I am happy to get more experience with templating.</p>
<p>I actually updated the <a class="link" href="https://gportal.link/" target="_blank" rel="noopener"
>gportal</a> main site to use html templates &ndash; it was easy to do and results in faster load times. Since it includes built in authentication service, it still has to be a hosted site, so I might as well use <a class="link" href="https://pkg.go.dev/html/template" target="_blank" rel="noopener"
>go html templates</a> to make it &ndash; which is just as easy and intuative as svelte.</p>
<h2 id="future-expectations-for-the-site">Future expectations for the site</h2>
<p>Ultimately, I just want this blog to look good, be feature rich, and not take any babysitting to keep it updated. All of these things are now possible thanks to hugo. I may even enable disqus comments soon, not that I think anyone lurking would actually want to post, but it would still be cool.</p>
<p>I plan to post more interesting posts with interactive data &ndash; another reason I am looking into adding custom js to each post.</p>
<p>I also wanted to post so I would have something here for 2024, now I do :)</p></description></item><item><title>Simplifying frontend frameworks</title><link>/blog/posts/2023/december/process_simplify_modules/</link><pubDate>Sun, 24 Dec 2023 00:00:00 +0000</pubDate><guid>/blog/posts/2023/december/process_simplify_modules/</guid><description><p>Disclosure: The words in this post were not AI-generated or altered in any meaningful way. Spell check and other tools were used, but all content and phrases are my own creation.</p>
<h2 id="introduction">Introduction</h2>
<p>I wrote an/other <a class="link" href="https://gportal.link/blog/blog/posts/2023/october/dependency-on-dependencies" >post</a> about
the frustration I have with frameworks in modern frontend software development.
The fast pace of change is hailed as the consequence of the innovative field of
front-end frameworks. It&rsquo;s a running joke that there&rsquo;s 10 new frameworks every
day. But I disagree this is simply a necessity of innovation.</p>
<p>Frontend frameworks evolve and change primarily because there is not and has
never been one good way to use javascript. No matter how flawed javascript is as
a programming language, it&rsquo;s biggest flaw is that it was woefully incomplete
from it&rsquo;s inception. The,re has never been good tooling for javascript. So this
massive void is constantly being filled with good-but-not-perfect solutions.
Heard of these: npm ? yarn? webpack? rollup? vite? bable? eslint? vite?
Typescript? I could go on and on. All these things that are typically built-in
to a language are all separate installable packages which are managed by
third-party maintainers. These maintainers have no obligation to keep up with
javascript changes or more devastatingly, changes to other tooling for
javascript. This compounds the main problem I have with frontend development&hellip;
Your frontend project will inevitably be crippled by incompatibilities. A
project is inevitably doomed to aging out due to vulnerabilities and old
tooling.</p>
<p>Maybe you retort, &ldquo;Don&rsquo;t be a developer if you can&rsquo;t handle it!&rdquo;? Well, that may
be true from a certain perspective. However, look at other languages &ndash; C, C++,
Golang, Rust, Java, C# (and many more) &ndash; can exist for decades and be easily
updated to new versions. They don&rsquo;t have this problem. I would actually say
(this leads to one of the ways I could deal with this), vanilla javascript also
fits into this category. decades old vanilla javascript projects still work &ndash;
they are simple to update for vulnerabilities. Vanilla javascript is one
solution to the framework issue. Albeit not the best solution, it does solve the
problem.</p>
<p>I have used vanilla javascript in a hackathon project at work to get an up and
running project going within a week. It worked great and was incredibly simple.
Yet, I had one coworker laughingly ask be if I really used vanilla javascript. I
said, &ldquo;yes, it works very well for this&rdquo;. A hackathon project is the perfect
scenario to skip a framework and just get something working.</p>
<p>A project becomes a devastatingly complicated web of
dependencies that needs solving if you want your project to continue on without
being marked legacy with thousands of vulnerabilities.</p>
<p>I maintain a fork of filebrowser/filebrowser, which I find entertaining to watch
their <a class="link" href="https://github.com/filebrowser/filebrowser/pull/2645" target="_blank" rel="noopener"
>effort</a> to upgrade
from vue2+webpack to vue3+vite. They have a multitude of half-implemented
attempts to get there. And another <a class="link" href="https://github.com/filebrowser/filebrowser/pull/2689" target="_blank" rel="noopener"
>main vue3
PR</a> which is in a
perpetual state of change for 6 months (still unmerged).</p>
<p>So, how did I handle this? Well, see <a class="link" href="#process-for-filebrowser" >my process below</a>, but
let me give a few examples. For now I want to dig into the problem more and what
I believe is <em>my solution</em>, which may not be yours because the problem is
systemic. The problem is javascript is a deeply flawed programming language
which is essential use to develope frontend webpages.</p>
<p>As an aside, some have said webassembly may solve this. I believe webassembly
will have a legacy similar to fusion energy &ndash; always being a few years out of
reach. My experience of webassembly has been full of frustration, but I could see
it being simplified in the future. However, I truly see it following the exact
same path as javascript. Meaning I see there being some usefully ways to
implement webassembly, but without a standardized way to implement it will be
doomed to fragmentation.</p>
<h2 id="examples">examples</h2>
<h3 id="process-for-filebrowser">Process for filebrowser</h3>
<p>My fork of filebrowser is superior to the original. Obviously, I am biased as
the maintainer. However, look - mine is <a class="link" href="https://hub.docker.com/layers/gtstef/filebrowser/latest/images/sha256-6574d5f4890a6a0aa2d995b9fd8856418b6fef34e3bdf774ae02cc209c78e650?context=repo" target="_blank" rel="noopener"
>half the
size</a>
of the
<a class="link" href="https://hub.docker.com/layers/filebrowser/filebrowser/latest/images/sha256-0e0a4b700302457772b07c4efc47bc90143d7538d36731baabcf7d375360bcee?context=explore" target="_blank" rel="noopener"
>original</a>,
runs faster, has better search, and is a better organized project from a
directory and tooling standpoint. Unlike the original, I can progressively
update and test the backend and frontend side-by-side in a live hot-reload
environment. This can&rsquo;t be done in the original implementation because they made
the choice to embed the frontend into the binary. I immediately separated them
after I forked it. That way neither the frontend or backend were dependant on
each other.</p>
<p>Obviously, a streamlined developer experience is a priority for me. So, how do I
handle updating the framework update to vue3? Well, originally I ignored it&hellip;
And Still, I have not updated it. But I am preparing. Rather than untangling</p>
<p>There is one example such as prettBytes module, which changed and caused the
filebrowser to stop displaying properly. The original repo maintainers <a class="link" href="https://github.com/filebrowser/filebrowser/pull/2779" target="_blank" rel="noopener"
>updated
it</a> to support the new
version of prettier. I did it differently, I replaced prettyBytes and
implemented it as <a class="link" href="https://github.com/gtsteffaniak/filebrowser/blob/main/frontend/src/utils/filesizes.js" target="_blank" rel="noopener"
>vanilla
javascript</a>
in 5 minutes.</p>
<p>So to migrate to vue3, my plan is to remove all modules with dependencies
requiring vue2 and instead of replacing them with new modules like the original
maintainers, I will implement it myself slowly over time removing all modules
from the dependencies. I am in no hurry! It will be worth the effort and I see
no need to move to vue3 now or in the future until my finally ocker images have
vulnerabilities. Right now they are squeaky clean - unlike the original which
has 12 vulnerabilities. Albeit, due to golang and OS&hellip; which I updated on the
first day. Not sure why they haven&rsquo;t addressed that.</p>
<p>Anyways, the only vulnerabilities in the workflow are due to npm packages for
dev tools only (not present in compiled output). These can&rsquo;t be resolved until I
stop using vue 2:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm i
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">up to date, audited <span class="m">766</span> packages in 4s
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="m">101</span> packages are looking <span class="k">for</span> funding
</span></span><span class="line"><span class="cl"> run <span class="sb">`</span>npm fund<span class="sb">`</span> <span class="k">for</span> details
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="m">4</span> moderate severity vulnerabilities
</span></span></code></pre></td></tr></table>
</div>
</div><p>so I created a copy <code>package.json</code> with comments to note which packages I need/plan to remove:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;dependencies&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;ace-builds&#34;</span><span class="p">:</span> <span class="s2">&#34;^1.24.2&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;clipboard&#34;</span><span class="p">:</span> <span class="s2">&#34;^2.0.4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;css-vars-ponyfill&#34;</span><span class="p">:</span> <span class="s2">&#34;^2.4.3&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;file-loader&#34;</span><span class="p">:</span> <span class="s2">&#34;^6.2.0&#34;</span><span class="p">,</span> <span class="c1">// UNNECESSARY IN VITE
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;js-base64&#34;</span><span class="p">:</span> <span class="s2">&#34;^2.5.1&#34;</span><span class="p">,</span> <span class="c1">// REPLACE WITH EQUIVALENT JS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;lodash.clonedeep&#34;</span><span class="p">:</span> <span class="s2">&#34;^4.5.0&#34;</span><span class="p">,</span> <span class="c1">// TOO OLD - REPLACE WITH JS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;lodash.throttle&#34;</span><span class="p">:</span> <span class="s2">&#34;^4.1.1&#34;</span><span class="p">,</span> <span class="c1">// TOO OLD - REPLACE WITH JS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;material-icons&#34;</span><span class="p">:</span> <span class="s2">&#34;^1.10.5&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;moment&#34;</span><span class="p">:</span> <span class="s2">&#34;^2.29.4&#34;</span><span class="p">,</span> <span class="c1">// REPLACE WITH EQUIVALENT JS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;normalize.css&#34;</span><span class="p">:</span> <span class="s2">&#34;^8.0.1&#34;</span><span class="p">,</span> <span class="c1">// REPLACE WITH EQUIVALENT JS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;noty&#34;</span><span class="p">:</span> <span class="s2">&#34;^3.2.0-beta&#34;</span><span class="p">,</span> <span class="c1">// REPLACE WITH EQUIVALENT JS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;pretty-bytes&#34;</span><span class="p">:</span> <span class="s2">&#34;^6.0.0&#34;</span><span class="p">,</span> <span class="c1">// REPLACE WITH EQUIVALENT JS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;qrcode.vue&#34;</span><span class="p">:</span> <span class="s2">&#34;^1.7.0&#34;</span><span class="p">,</span> <span class="c1">// UPDATE TO LATEST for VUE3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;utif&#34;</span><span class="p">:</span> <span class="s2">&#34;^3.1.0&#34;</span><span class="p">,</span> <span class="c1">// SPIKE investigate replacement
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;vue&#34;</span><span class="p">:</span> <span class="s2">&#34;^2.6.10&#34;</span><span class="p">,</span> <span class="c1">// UPDATE to vue 3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;vue-async-computed&#34;</span><span class="p">:</span> <span class="s2">&#34;^3.9.0&#34;</span><span class="p">,</span> <span class="c1">// REPLACE WITH EQUIVALENT JS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;vue-i18n&#34;</span><span class="p">:</span> <span class="s2">&#34;^8.15.3&#34;</span><span class="p">,</span> <span class="c1">// REMOVE
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;vue-lazyload&#34;</span><span class="p">:</span> <span class="s2">&#34;^1.3.3&#34;</span><span class="p">,</span> <span class="c1">// REMOVE
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;vue-router&#34;</span><span class="p">:</span> <span class="s2">&#34;^3.1.3&#34;</span><span class="p">,</span> <span class="c1">// UPDATE to vue 3 @vue4 https://www.npmjs.com/package/vue-router
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;vue-simple-progress&#34;</span><span class="p">:</span> <span class="s2">&#34;^1.1.1&#34;</span><span class="p">,</span> <span class="c1">// REPLACE WITH EQUIVALENT JS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;vuex&#34;</span><span class="p">:</span> <span class="s2">&#34;^3.1.2&#34;</span><span class="p">,</span> <span class="c1">// SPIKE: HOW TO REMOVE
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;vuex-router-sync&#34;</span><span class="p">:</span> <span class="s2">&#34;^5.0.0&#34;</span><span class="p">,</span> <span class="c1">// SPIKE: HOW TO REMOVE
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;whatwg-fetch&#34;</span><span class="p">:</span> <span class="s2">&#34;^3.6.2&#34;</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;devDependencies&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;@vue/cli-service&#34;</span><span class="p">:</span> <span class="s2">&#34;^5.0.8&#34;</span><span class="p">,</span> <span class="c1">// REMOVE for VUE3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;compression-webpack-plugin&#34;</span><span class="p">:</span> <span class="s2">&#34;^10.0.0&#34;</span><span class="p">,</span> <span class="c1">// REPLACE VUE3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">&#34;eslint&#34;</span><span class="p">:</span> <span class="s2">&#34;^8.51.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;eslint-plugin-vue&#34;</span><span class="p">:</span> <span class="s2">&#34;^9.17.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;vue-template-compiler&#34;</span><span class="p">:</span> <span class="s2">&#34;^2.6.10&#34;</span> <span class="c1">// REPLACE VUE3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>You can see I plan to remove the vast majority of packages. That is one solution
I have to this. As always, this doesn&rsquo;t fully resolve the long-term
maintainability problem. But it does do one thing, it means when the day comes I
need to change frameworks, it will be much simpler because my frontend won&rsquo;t
depend on packages that depend on a certain framework.</p>
<p>The next perfectly reasonable package to drop will be js-base64 which&hellip; not
sure why they needed considering javascript has native base64 encoding/decode
support.</p>
<p>To make this work, I would just update this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">Base64</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;js-base64&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">Base64</span><span class="p">.</span><span class="nx">decode</span><span class="p">(</span><span class="nx">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">]));</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>to this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">atob</span><span class="p">(</span><span class="nx">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">]));</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Do you see that? In order to remove one more package, I spent 5 seconds
replacing one line. Not all packages will be that easy, but that&rsquo;s still one less
package to worry about. Why didn&rsquo;t the original owners do that? Probably because of
laziness. They chose to searching the package manager for a solution to their
problem rather than spending a few seconds or minutes to see if they could do it
themselves. Lazy lazy lazy.</p>
<p>That was so easy lets do another right now. Lets look at prettyBytes, a very
similar problem to one I mentioned already with prettier - oh look I already have my own library.</p>
<p>So to remove this module I can just change this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">prettyBytes</span> <span class="nx">from</span> <span class="s2">&#34;pretty-bytes&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="nx">usageStats</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">used</span><span class="o">:</span> <span class="nx">prettyBytes</span><span class="p">(</span><span class="nx">usage</span><span class="p">.</span><span class="nx">used</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">,</span> <span class="p">{</span> <span class="nx">binary</span><span class="o">:</span> <span class="kc">true</span> <span class="p">}),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">total</span><span class="o">:</span> <span class="nx">prettyBytes</span><span class="p">(</span><span class="nx">usage</span><span class="p">.</span><span class="nx">total</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">,</span> <span class="p">{</span> <span class="nx">binary</span><span class="o">:</span> <span class="kc">true</span> <span class="p">}),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">usedPercentage</span><span class="o">:</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">((</span><span class="nx">usage</span><span class="p">.</span><span class="nx">used</span> <span class="o">/</span> <span class="nx">usage</span><span class="p">.</span><span class="nx">total</span><span class="p">)</span> <span class="o">*</span> <span class="mi">100</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>to this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">getHumanReadableFilesize</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;@/utils/filesizes&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">usageStats</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">used</span><span class="o">:</span> <span class="nx">getHumanReadableFilesize</span><span class="p">(</span><span class="nx">usage</span><span class="p">.</span><span class="nx">used</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">total</span><span class="o">:</span> <span class="nx">getHumanReadableFilesize</span><span class="p">(</span><span class="nx">usage</span><span class="p">.</span><span class="nx">total</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">,),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">usedPercentage</span><span class="o">:</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">((</span><span class="nx">usage</span><span class="p">.</span><span class="nx">used</span> <span class="o">/</span> <span class="nx">usage</span><span class="p">.</span><span class="nx">total</span><span class="p">)</span> <span class="o">*</span> <span class="mi">100</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Wow. So easy, right? Well, thats two packages less&hellip; These are the easiest
examples to do. Many others will be much more difficult. However, I am in no
hurry. Everything still works on vue2 , but I would like to get rid of the pesky
github bot complaining about vulnerabilities. I will eventually fix it, but over
time, slowly, over multiple commits. Hopefully that will allow me to avoid the
problem the original maintainers have trying to merge the big PR thats stuck in
limbo.</p>
<h2 id="final-thoughts">Final thoughts</h2>
<p>As for lessons for the future - Always think about how long you want your
project to exist. The more maintenance that is required, the more quickly it
will fall into disrepair. I will continue to think about ways to implement
simple, natively supported solutions to challenges. I think this will save me
time and keep my projects living longer on their own.</p></description></item><item><title>Happy Holidays!</title><link>/blog/posts/2023/december/happy_holidays/</link><pubDate>Fri, 22 Dec 2023 00:00:00 +0000</pubDate><guid>/blog/posts/2023/december/happy_holidays/</guid><description><p>Happy Holidays! (see <a class="link" href="https://gportal.link/blog/old/?posts/2023/December/happy_holidays.md" target="_blank" rel="noopener"
>original blog post</a> for a better experience)</p></description></item><item><title>The doubled edge sword of modules when developing</title><link>/blog/posts/2023/october/dependency-on-dependencies/</link><pubDate>Thu, 19 Oct 2023 00:00:00 +0000</pubDate><guid>/blog/posts/2023/october/dependency-on-dependencies/</guid><description><p>Disclosure: The words in this post were not AI-generated or altered in any meaningful way. Spell check and other tools were used, but all content and phrases are my own creation.</p>
<blockquote>
<p>Note: In this post, I will use the term &ldquo;external module&rdquo; to refer to an
external package dependency that is imported into a program when developing.</p>
</blockquote>
<h2 id="introduction">Introduction</h2>
<p>When designing and creating projects in any language and framework there is a
choice that every developer has to make. What modules should you use? This
choice has implications for many different things. <em>Personally</em>, I find it is
best to exercise judicial usage of external models when developing for several
reasons.</p>
<p>No matter what language or framework you choose to make your world-changing
program in, the choice is constantly presenting itself. There are always going
to be corners that you would rather import an external module that already has
everything figured out - do you want to reinvent the wheel everywhere? Here are
a few examples where it might be obvious to use an external module:</p>
<ol>
<li>For security-oriented features&hellip; using reputable external modules could
ensure security.</li>
<li>Using &ldquo;frameworks&rdquo; to accomplish complicated plumbing. If something would be
an entire project on its own, you obviously wouldn&rsquo;t want to double or triple
the work you have cut out for yourself.</li>
<li>For API functions and interoperability with other programs. If an SDK or API
framework is provided in the target language that you need to use, it doesn&rsquo;t
make any sense to code it yourself.</li>
</ol>
<p>The above scenarios are undisputed reasons to import external modules in my
opinion. As long as the authors of the external modules are reputable and the
modules are in active development themselves, I don&rsquo;t see any reason not to use
external modules.</p>
<p>The problem comes from every other scenario.</p>
<p><strong>My main point:</strong></p>
<blockquote>
<p>If you are considering importing modules for functions you could accomplish
yourself in a reasonably short time, it would be well worth the effort to do it
yourself instead of relying on external modules.</p>
</blockquote>
<h2 id="advantages-of-using-external-modules">Advantages of using external modules</h2>
<p>Let&rsquo;s take a look at all the reasons you might want to use external modules.</p>
<p>External modules&hellip;</p>
<ol>
<li>Initially save you time! Sometimes a significant amount of time.</li>
<li>Can do things very well. Sometimes much better than you could do something
yourself in a short amount of time.</li>
<li>May add features over time without any effort needed from you.</li>
<li>Allow you to focus on the code in your program rather than being distracted
by solving challenges unrelated to your project.</li>
</ol>
<p>These are all massive benefits that mostly revolve around saving developer&rsquo;s
time. That is a very important factor in decision-making. However, there is a
lurking issue with this. It&rsquo;s like investing, the upfront cost and appearance of
implementing your solutions instead of using external modules may appear higher,
but I believe it is much lower over time.</p>
<p>So let&rsquo;s talk about the downsides.</p>
<h1 id="disadvantages-of-using-external-modules">Disadvantages of using external modules</h1>
<p>Let&rsquo;s identify some concerns I have with external modules.</p>
<p>External modules&hellip;</p>
<ol>
<li>Introduce risk for dependencies versioning conflicts. As dependency
requirements drift over time, your program may find itself in a state of
dependency conflict because two external modules depend on different versions
of a shared indirect dependency.</li>
<li>Introduce security risks that are out of your control. If a module has a
vulnerability or other security-related issues, you must wait for your module
to fix the vulnerability before your entire program can be fixed.</li>
<li>Limit your ability to tailor the functions to your needs. If you use
dependencies to accomplish something, you are often limited to the features
of the third-party external module.</li>
<li>Can introduce performance/stability challenges. You may not have control over
how a function is accomplished in an external module. It&rsquo;s common that issues
such as memory leak or performance degradations exists or is introduced in
new versions, and as the user of a module, you may be powerless to control
it.</li>
<li>Introduces more complicated compiling and install operations. Using external
modules means downloading and installing them, which may not be a huge deal
depending on the module&rsquo;s size. However liberal usage of modules adds up and
can cause this to be a challenge. It may also quickly balloon your program&rsquo;s
size (looking at you <code>Python</code>).</li>
</ol>
<p>Finally, I can vent my frustrations with external modules. I find it frustrating
how common the pattern is: a developer introduces an external module to do a
simple task that they could easily accomplish themselves. Then, because of this,
the program is bigger and more bloated. However, the primary issue is over time,
as the additional complexities make the program more difficult to maintain.</p>
<p>I think the biggest offender to version conflicts and vulnerabilities is<code>NPM</code>.
When someone creates a project, they often use npm packages to accomplish the
most basic and mundane tasks: button styles, formatting strings like date/time,
loading bars/spinners, HTML formatting, etc. These are things that would
literally take 5 minutes to implement without installing additional packages. It
quickly brings a project to life &ndash; it works and looks great for a MOMENT. Then,
in the weeks or months, it drifts into version conflict, accumulates
vulnerabilities, and receives updates that cause functions to not work the same
as they originally did. This requires extra time from the developer to identify,
refactor, and attempt to resolve each issue&hellip; constantly for the remaining time
the program exists. Eventually, the developer loses interest and the program is
no longer maintained&hellip; stuck with older versions that have vulnerabilities and
conflicts that prevent it from being renewed.</p>
<p><strong>sigh</strong> ok, give me a moment.</p>
<p>Ok - so you get the picture? I mentioned <code>NPM</code>, but the truth is that every
language and program has this. NPM is just the most likely to fall victim for
several reasons. However, <code>Python</code> can have complicated PIP requirements, <code>Go</code>
can have a long list of modules to download for compile-time, <code>Java</code> can get
caught up on maven conflicts or broken builds from updates. Javascript
Frameworks like <code>React</code>, <code>Svelte</code>, and <code>Vue.js</code> can all be complicated to
upgrade from version to version. It&rsquo;s a challenge everywhere.</p>
<h2 id="bottom-line">Bottom line</h2>
<p>Here&rsquo;s the point, using external modules saves you time as a developer up front.
You must consider and weigh the time savings with the possible time requirements
in the future to maintain the codebase. It may be hard to calculate the costs
for future maintenance, but I understand that. However, if you care for the
program that you are investing in to exist over time, these future time
investment costs must be considered.</p>
<p>My rule that I have come to is pretty simple: If I can mostly accomplish
something within 30 minutes on my own, don&rsquo;t even bother looking for an external
module. If It would take more than 30 minutes but is still something I <em>could</em>
accomplish fairly easily. In that case, use a module for now, but track it for
replacement with your implementation eventually. For everything else, I suck it
up and deal with the challenges and necessary evil of dependencies.</p>
<h3 id="further-reading">Further reading</h3>
<p>I hope you found this informative. I would love to give examples of these types
of issues I have run into. I plan to update with another post showing these
examples and how I fixed them quickly without external modules.</p>
<p>I didn&rsquo;t mention this, but it&rsquo;s often much easier to make your program without
modules. So, it&rsquo;s not always time-saving to use modules. I plan to give examples
on this and I will link it here in the future.</p></description></item><item><title>Comparing Go, Rust, and C++: A Deep Dive into Language Performance and Tooling</title><link>/blog/posts/2023/september/comparing_compiled/</link><pubDate>Tue, 22 Aug 2023 00:00:00 +0000</pubDate><guid>/blog/posts/2023/september/comparing_compiled/</guid><description><p>Disclosure: AI was used in the process of writing this article.</p>
<blockquote>
<p><strong>NOTE</strong>
Go or what is informally known as &ldquo;GoLang&rdquo; will be referred to by its official name &ldquo;Go&rdquo;. The name &ldquo;Go&rdquo; also emphasizes its simplicity and ease of use.</p>
</blockquote>
<p>As software development continues to evolve, developers often find themselves faced with a crucial decision: choosing the right programming language for their projects. In this blog post, we&rsquo;ll compare and contrast these three languages in terms of compile time, binary size, general performance, garbage collection, modern tooling differences, and which is best for new developers.</p>
<h2 id="compile-time">Compile Time</h2>
<p><strong>Go:</strong> One of Go&rsquo;s standout features is its blazing-fast compile times. It excels in this area due to its simplicity and a focus on concurrent compilation. Even for large projects, Go compiles in a matter of seconds, making it a preferred choice for projects with tight development cycles. Go excels with average compile times of &lt; 1 second even for large projects due to its simple design and concurrent compilation.<a class="link" href="https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-go.html" target="_blank" rel="noopener"
>[1]</a></p>
<p><strong>Rust:</strong> Rust&rsquo;s compile times are generally longer compared to Go, primarily because of its more advanced type system and borrow checker. However, the trade-off is robust memory safety. The Rust compiler ensures memory safety without relying on garbage collection, which makes the extra compilation time worthwhile for many developers.</p>
<p><strong>C++:</strong> While modern C++ standards (C++11 and beyond) have introduced features to improve compilation speed, large codebases can still result in lengthy compile times. C++ provides fine-grained control over compilation, but this power can come at the cost of slower development feedback loops.</p>
<h2 id="binary-size">Binary Size</h2>
<p><strong>Go:</strong> Go is renowned for producing compact, statically-linked binaries. This is advantageous for applications where a small memory footprint is crucial, such as cloud-native microservices. Go&rsquo;s runtime includes a garbage collector, which can increase binary size slightly, but it remains efficient.</p>
<p><strong>Rust:</strong> Rust&rsquo;s binaries are typically smaller than those produced by Go for smaller projects. However, the larger the project gets, the binary sizes become very comparable.</p>
<p><strong>C++:</strong> C++ binaries can be quite large, especially when using libraries or features that introduce substantial runtime overhead. While C++ allows for low-level optimization to reduce binary size, developers need to carefully manage dependencies and compiler flags to achieve smaller executables.</p>
<p>Comparisons</p>
<h2 id="general-performance">General Performance</h2>
<p><strong>Go:</strong> Go is designed for excellent runtime performance. Its goroutine-based concurrency model is efficient and makes it easy to write concurrent programs. While it may not match the raw performance of C++ in certain scenarios, it&rsquo;s often considered &ldquo;fast enough&rdquo; for many use cases. In practice this means a 0-30% reduction in speed as compared to Rust or C++.</p>
<p><strong>Rust:</strong> Rust is known for its focus on performance and safety. It can achieve C++ levels of performance by providing low-level control over memory management without sacrificing safety. Rust&rsquo;s ownership and borrowing system allow developers to write high-performance code with confidence.</p>
<p><strong>C++:</strong> C++ is renowned for its performance and versatility. It&rsquo;s a systems programming language that allows developers to optimize code for specific hardware and performance-critical applications. However, this level of control comes with a steeper learning curve and increased development complexity.</p>
<h2 id="garbage-collection">Garbage Collection</h2>
<p><strong>Go (Golang):</strong> Go employs a garbage collector, which simplifies memory management for developers. While garbage collection introduces a minimal runtime overhead, Go&rsquo;s efficient design often offsets this impact. Developers can focus on writing code rather than managing memory. <a class="link" href="https://tip.golang.org/doc/gc-guide" target="_blank" rel="noopener"
>[2]</a></p>
<p><strong>Rust:</strong> The Rust programming language relies on a strict ownership system, ensuring memory safety at compile-time. This approach eliminates the runtime overhead associated with garbage collection, making Rust suitable for systems programming and high-performance applications.</p>
<p><strong>C++:</strong> C++ doesn&rsquo;t include a built-in garbage collector, giving developers complete control over memory management. However, this control can lead to memory-related bugs if not managed carefully. Developers must manually allocate and deallocate memory, which can be error-prone and extra effort. <a class="link" href="https://stackoverflow.com/questions/4687310/memory-allocation-in-c" target="_blank" rel="noopener"
>[3]</a></p>
<h2 id="modern-tooling-differences">Modern Tooling Differences</h2>
<p><strong>Go:</strong> Go comes with a comprehensive standard library and excellent tooling. Tools like <code>go fmt</code> for code formatting, <code>go test</code> for testing and coverage, and <code>go mod</code> for dependency management are integral to the Go ecosystem. Go&rsquo;s tooling promotes consistency and efficiency.</p>
<p><strong>Rust:</strong> Rust&rsquo;s tooling has made significant strides in recent years. It boasts tools like <code>Cargo</code> for dependency management, building, and testing. Rust&rsquo;s package manager, crates.io, offers a vast collection of libraries. The Rust community values robust tooling to ensure a smooth development experience.</p>
<p><strong>C++:</strong> C++ tooling can vary significantly depending on the chosen compiler and build system. While modern build systems like CMake and tools like Clang and GCC have improved C++ development, it can be more challenging for newcomers to navigate.</p>
<h2 id="best-for-new-developers">Best for New Developers</h2>
<p>Go stands out as the ultimate champion for general purpose developer tasks if performance is a key focus. Its simplicity, clean syntax, and thoughtful design make it an excellent starting point for beginners. The Go community places a strong emphasis on beginner-friendly practices and provides outstanding documentation and resources. Moreover, Go&rsquo;s lightning-fast compilation times ensure that new developers receive quick feedback, enhancing the learning experience.</p>
<p>While Rust and C++ have their merits in terms of performance and control, they come with steeper learning curves and complexities that might overwhelm newcomers. Go, on the other hand, empowers new developers to dive right into coding, fostering a positive and productive environment for learning and building software.</p>
<p>In conclusion, for those starting their programming journey or looking for a language that promotes rapid skill development, Go is the undisputed choice. Its beginner-friendly nature, extensive resources, and efficient tooling make it the perfect language for new developers to embark on their coding adventures.</p></description></item><item><title>My experience benchmarking llama</title><link>/blog/posts/2023/may/llama-cpp-tests/</link><pubDate>Sun, 14 May 2023 00:00:00 +0000</pubDate><guid>/blog/posts/2023/may/llama-cpp-tests/</guid><description><p>Disclosure: The words in this post were not AI-generated or altered in any meaningful way. Spell check and other tools were used, but all content and phrases are my own creation.</p>
<p>Today, I had the opportunity to benchmark a fascinating program called &ldquo;llama.cpp&rdquo; that has been ported to work with multiple programming languages, including Python and Golang. As an enthusiast of both Python and Golang, I was particularly interested in comparing the performance of these two implementations on my M1 Arm64 MacBook.</p>
<p>In this benchmark, I tested three different implementations:</p>
<ul>
<li><a class="link" href="https://github.com/ggerganov/llama.cpp" target="_blank" rel="noopener"
>llama.cpp</a></li>
<li><a class="link" href="https://github.com/gotzmann/llama.go" target="_blank" rel="noopener"
>llama.go</a></li>
</ul>
<p>Naturally, you might be curious about which implementation performed the fastest. It&rsquo;s worth noting that the native version of llama.cpp is likely to have the advantage in terms of speed. This advantage stems not from the inherent speed of the programming language but rather from the fact that it is the &ldquo;upstream&rdquo; branch that receives all the changes and performance optimizations first. Consequently, the Python and Golang versions may not have benefited from these optimizations yet.</p>
<h2 id="llamacpp">llama.cpp</h2>
<p>execution:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="o">./</span><span class="n">main</span> <span class="o">-</span><span class="n">m</span> <span class="o">~/</span><span class="n">models</span><span class="o">/</span><span class="n">llama</span><span class="o">-</span><span class="mi">7</span><span class="n">b</span><span class="o">-</span><span class="n">fp32</span><span class="o">.</span><span class="n">bin</span> <span class="o">-</span><span class="n">c</span> <span class="mi">45</span> <span class="o">-</span><span class="n">n</span> <span class="mi">45</span>
</span></span><span class="line"><span class="cl"><span class="n">main</span><span class="p">:</span> <span class="n">build</span> <span class="o">=</span> <span class="mi">548</span> <span class="p">(</span><span class="mi">60</span><span class="n">f8c36</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">main</span><span class="p">:</span> <span class="nb">seed</span> <span class="o">=</span> <span class="mi">1684077400</span>
</span></span><span class="line"><span class="cl"><span class="n">llama</span><span class="o">.</span><span class="n">cpp</span><span class="p">:</span> <span class="n">loading</span> <span class="n">model</span> <span class="n">from</span> <span class="o">/</span><span class="n">Users</span><span class="o">/</span><span class="n">steffag</span><span class="o">/</span><span class="n">models</span><span class="o">/</span><span class="n">llama</span><span class="o">-</span><span class="mi">7</span><span class="n">b</span><span class="o">-</span><span class="n">fp32</span><span class="o">.</span><span class="n">bin</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">format</span> <span class="o">=</span> <span class="n">ggjt</span> <span class="n">v1</span> <span class="p">(</span><span class="n">pre</span> <span class="c1">#1405)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_vocab</span> <span class="o">=</span> <span class="mi">32000</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_ctx</span> <span class="o">=</span> <span class="mi">45</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_embd</span> <span class="o">=</span> <span class="mi">4096</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_mult</span> <span class="o">=</span> <span class="mi">256</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_head</span> <span class="o">=</span> <span class="mi">32</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_layer</span> <span class="o">=</span> <span class="mi">32</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_rot</span> <span class="o">=</span> <span class="mi">128</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">ftype</span> <span class="o">=</span> <span class="mi">0</span> <span class="p">(</span><span class="n">all</span> <span class="n">F32</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_ff</span> <span class="o">=</span> <span class="mi">11008</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_parts</span> <span class="o">=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">model</span> <span class="n">size</span> <span class="o">=</span> <span class="mi">7</span><span class="n">B</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">ggml</span> <span class="n">ctx</span> <span class="n">size</span> <span class="o">=</span> <span class="mf">72.75</span> <span class="n">KB</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">mem</span> <span class="n">required</span> <span class="o">=</span> <span class="mf">27497.09</span> <span class="n">MB</span> <span class="p">(</span><span class="o">+</span> <span class="mf">1026.00</span> <span class="n">MB</span> <span class="n">per</span> <span class="n">state</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_init_from_file</span><span class="p">:</span> <span class="n">kv</span> <span class="bp">self</span> <span class="n">size</span> <span class="o">=</span> <span class="mf">22.50</span> <span class="n">MB</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">system_info</span><span class="p">:</span> <span class="n">n_threads</span> <span class="o">=</span> <span class="mi">8</span> <span class="o">/</span> <span class="mi">10</span> <span class="o">|</span> <span class="n">AVX</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">AVX2</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">AVX512</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">AVX512_VBMI</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">AVX512_VNNI</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">FMA</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">NEON</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">|</span> <span class="n">ARM_FMA</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">|</span> <span class="n">F16C</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">FP16_VA</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">|</span> <span class="n">WASM_SIMD</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">BLAS</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">|</span> <span class="n">SSE3</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">VSX</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">|</span>
</span></span><span class="line"><span class="cl"><span class="n">sampling</span><span class="p">:</span> <span class="n">repeat_last_n</span> <span class="o">=</span> <span class="mi">64</span><span class="p">,</span> <span class="n">repeat_penalty</span> <span class="o">=</span> <span class="mf">1.100000</span><span class="p">,</span> <span class="n">presence_penalty</span> <span class="o">=</span> <span class="mf">0.000000</span><span class="p">,</span> <span class="n">frequency_penalty</span> <span class="o">=</span> <span class="mf">0.000000</span><span class="p">,</span> <span class="n">top_k</span> <span class="o">=</span> <span class="mi">40</span><span class="p">,</span> <span class="n">tfs_z</span> <span class="o">=</span> <span class="mf">1.000000</span><span class="p">,</span> <span class="n">top_p</span> <span class="o">=</span> <span class="mf">0.950000</span><span class="p">,</span> <span class="n">typical_p</span> <span class="o">=</span> <span class="mf">1.000000</span><span class="p">,</span> <span class="n">temp</span> <span class="o">=</span> <span class="mf">0.800000</span><span class="p">,</span> <span class="n">mirostat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">mirostat_lr</span> <span class="o">=</span> <span class="mf">0.100000</span><span class="p">,</span> <span class="n">mirostat_ent</span> <span class="o">=</span> <span class="mf">5.000000</span>
</span></span><span class="line"><span class="cl"><span class="n">generate</span><span class="p">:</span> <span class="n">n_ctx</span> <span class="o">=</span> <span class="mi">45</span><span class="p">,</span> <span class="n">n_batch</span> <span class="o">=</span> <span class="mi">512</span><span class="p">,</span> <span class="n">n_predict</span> <span class="o">=</span> <span class="mi">45</span><span class="p">,</span> <span class="n">n_keep</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="err">←</span> <span class="n">The</span> <span class="n">Forgotten</span> <span class="n">Story</span> <span class="n">of</span> <span class="n">the</span> <span class="n">First</span> <span class="n">Civil</span> <span class="n">War</span> <span class="n">Battle</span> <span class="ow">in</span> <span class="n">Kansas</span>
</span></span><span class="line"><span class="cl"><span class="n">Making</span> <span class="n">It</span> <span class="n">Home</span> <span class="n">from</span> <span class="n">the</span> <span class="n">Front</span> <span class="err">→</span>
</span></span><span class="line"><span class="cl"><span class="n">I</span> <span class="n">Have</span> <span class="n">a</span> <span class="n">Dream</span><span class="err">—</span><span class="n">That</span> <span class="n">We</span> <span class="n">Finally</span> <span class="n">Learn</span> <span class="n">More</span> <span class="n">About</span> <span class="n">Frederick</span> <span class="n">Douglass</span><span class="o">!</span>
</span></span><span class="line"><span class="cl"><span class="err">“</span><span class="n">I</span> <span class="n">have</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="nb">load</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">9196.58</span> <span class="n">ms</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="n">sample</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">22.49</span> <span class="n">ms</span> <span class="o">/</span> <span class="mi">45</span> <span class="n">runs</span> <span class="p">(</span> <span class="mf">0.50</span> <span class="n">ms</span> <span class="n">per</span> <span class="n">token</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="n">prompt</span> <span class="n">eval</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">10716.26</span> <span class="n">ms</span> <span class="o">/</span> <span class="mi">25</span> <span class="n">tokens</span> <span class="p">(</span> <span class="mf">428.65</span> <span class="n">ms</span> <span class="n">per</span> <span class="n">token</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="n">eval</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">11689.89</span> <span class="n">ms</span> <span class="o">/</span> <span class="mi">43</span> <span class="n">runs</span> <span class="p">(</span> <span class="mf">271.86</span> <span class="n">ms</span> <span class="n">per</span> <span class="n">token</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="n">total</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">22483.24</span> <span class="n">ms</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Memory usage : 35 MB
CPU usage : 85%</p>
<p>OK! Easy enough. It took 11 seconds to print, with <strong>272 ms per token</strong>!</p>
<h2 id="go-llama">Go llama</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">LIBRARY_PATH</span><span class="o">=$</span><span class="n">PWD</span> <span class="n">C_INCLUDE_PATH</span><span class="o">=$</span><span class="n">PWD</span> <span class="n">go</span> <span class="n">run</span> <span class="o">./</span><span class="n">examples</span> <span class="o">-</span><span class="n">m</span> <span class="o">~/</span><span class="n">models</span><span class="o">/</span><span class="n">llama</span><span class="o">-</span><span class="mi">7</span><span class="n">b</span><span class="o">-</span><span class="n">fp32</span><span class="o">.</span><span class="n">bin</span> <span class="o">-</span><span class="n">n</span> <span class="mi">45</span>
</span></span><span class="line"><span class="cl"><span class="n">llama</span><span class="o">.</span><span class="n">cpp</span><span class="p">:</span> <span class="n">loading</span> <span class="n">model</span> <span class="n">from</span> <span class="o">/</span><span class="n">Users</span><span class="o">/</span><span class="n">steffag</span><span class="o">/</span><span class="n">models</span><span class="o">/</span><span class="n">llama</span><span class="o">-</span><span class="mi">7</span><span class="n">b</span><span class="o">-</span><span class="n">fp32</span><span class="o">.</span><span class="n">bin</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">format</span> <span class="o">=</span> <span class="n">ggjt</span> <span class="n">v1</span> <span class="p">(</span><span class="n">pre</span> <span class="c1">#1405)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_vocab</span> <span class="o">=</span> <span class="mi">32000</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_ctx</span> <span class="o">=</span> <span class="mi">128</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_embd</span> <span class="o">=</span> <span class="mi">4096</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_mult</span> <span class="o">=</span> <span class="mi">256</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_head</span> <span class="o">=</span> <span class="mi">32</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_layer</span> <span class="o">=</span> <span class="mi">32</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_rot</span> <span class="o">=</span> <span class="mi">128</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">ftype</span> <span class="o">=</span> <span class="mi">0</span> <span class="p">(</span><span class="n">all</span> <span class="n">F32</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_ff</span> <span class="o">=</span> <span class="mi">11008</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">n_parts</span> <span class="o">=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">model</span> <span class="n">size</span> <span class="o">=</span> <span class="mi">7</span><span class="n">B</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">ggml</span> <span class="n">ctx</span> <span class="n">size</span> <span class="o">=</span> <span class="mf">68.20</span> <span class="n">KB</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_model_load_internal</span><span class="p">:</span> <span class="n">mem</span> <span class="n">required</span> <span class="o">=</span> <span class="mf">27497.08</span> <span class="n">MB</span> <span class="p">(</span><span class="o">+</span> <span class="mf">2052.00</span> <span class="n">MB</span> <span class="n">per</span> <span class="n">state</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_init_from_file</span><span class="p">:</span> <span class="n">kv</span> <span class="bp">self</span> <span class="n">size</span> <span class="o">=</span> <span class="mf">128.00</span> <span class="n">MB</span>
</span></span><span class="line"><span class="cl"><span class="n">The</span> <span class="n">model</span> <span class="n">loaded</span> <span class="n">successfully</span><span class="o">.</span>
</span></span><span class="line"><span class="cl"><span class="o">&gt;&gt;&gt;</span> <span class="n">What</span> <span class="n">is</span> <span class="n">the</span> <span class="n">fastest</span> <span class="n">programming</span> <span class="n">language</span><span class="err">?</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">Sending</span> <span class="n">what</span> <span class="n">is</span> <span class="n">the</span> <span class="n">fastest</span> <span class="n">programming</span> <span class="n">language</span><span class="err">?</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">by</span> <span class="n">Cary</span> <span class="n">R</span> <span class="n">on</span> <span class="n">Jul</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">2017</span><span class="p">,</span> <span class="n">at</span> <span class="mi">6</span><span class="p">:</span><span class="mi">45</span> <span class="n">UTC</span>
</span></span><span class="line"><span class="cl"><span class="n">what</span> <span class="k">do</span> <span class="n">you</span> <span class="n">think</span> <span class="n">it</span> <span class="n">is</span> <span class="ow">and</span> <span class="n">why</span><span class="err">?</span>
</span></span><span class="line"><span class="cl"><span class="n">I</span><span class="s1">&#39;m not sure what &#34;fast&#34; means for this</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="nb">load</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">99393.39</span> <span class="n">ms</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="n">sample</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">32.26</span> <span class="n">ms</span> <span class="o">/</span> <span class="mi">45</span> <span class="n">runs</span> <span class="p">(</span> <span class="mf">0.72</span> <span class="n">ms</span> <span class="n">per</span> <span class="n">token</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="n">prompt</span> <span class="n">eval</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">5021.80</span> <span class="n">ms</span> <span class="o">/</span> <span class="mi">10</span> <span class="n">tokens</span> <span class="p">(</span> <span class="mf">502.18</span> <span class="n">ms</span> <span class="n">per</span> <span class="n">token</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="n">eval</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">15193.51</span> <span class="n">ms</span> <span class="o">/</span> <span class="mi">44</span> <span class="n">runs</span> <span class="p">(</span> <span class="mf">345.31</span> <span class="n">ms</span> <span class="n">per</span> <span class="n">token</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">llama_print_timings</span><span class="p">:</span> <span class="n">total</span> <span class="n">time</span> <span class="o">=</span> <span class="mf">115311.61</span> <span class="n">ms</span>
</span></span><span class="line"><span class="cl"><span class="n">Embeddings</span><span class="p">:</span> <span class="p">[</span><span class="mf">1.3335894</span> <span class="o">-</span><span class="mf">0.83280444</span> <span class="mf">0.9414267</span> <span class="o">-</span><span class="mf">9.215284</span> <span class="o">-</span><span class="mf">1.0302917</span> <span class="mf">1.065452</span> <span class="o">-</span><span class="mf">0.4542901</span> <span class="o">-</span><span class="mf">0.24896632</span> <span class="o">-</span><span class="mf">0.6570409</span> <span class="mf">1.9119468</span> <span class="mf">0.6292349</span> <span class="o">-</span><span class="mf">0.14391524</span> <span class="mf">0.2595427</span> <span class="o">-</span><span class="mf">0.5855895</span> <span class="o">-</span><span class="mf">0.963376</span> <span class="mf">1.0406973</span> <span class="o">-</span><span class="mf">0.1605502</span> <span class="mf">1.3280734</span> <span class="mf">0.37920082</span> <span class="mf">0.61060756</span> <span class="o">-</span><span class="mf">1.2766573</span> <span class="o">-</span><span class="mf">1.8673204</span> <span class="mf">1.2690753</span> <span class="o">-</span><span class="mf">0.4294657</span> <span class="mf">0.5546539</span> <span class="mf">0.11715727</span> <span class="mf">0.6430202</span> <span class="o">-</span><span class="mf">0.09789314</span> <span class="o">-</span><span class="mf">0.45095867</span> <span class="o">-</span><span class="mf">1.1076287</span> <span class="mf">0.042604066</span> <span class="mf">0.15544033</span> <span class="o">-</span><span class="mf">0.09977249</span> <span class="o">-</span><span class="mf">1.3832492</span> <span class="mf">0.018180523</span> <span class="mf">2.2709634</span> <span class="mf">0.26105422</span> <span class="o">-</span><span class="mf">1.0794421</span> <span class="mf">0.28251836</span> <span class="o">-</span><span class="mf">1.2772827</span> <span class="mf">1.3353819</span> <span class="o">-</span><span class="mf">1.1416842</span> <span class="mf">1.8800831</span> <span class="mf">0.7737296</span> <span class="mf">0.8329498</span> <span class="o">-</span><span class="mf">1.1428409</span> <span class="o">-</span><span class="mf">0.27773026</span> <span class="mf">0.59615296</span> <span class="o">-</span><span class="mf">1.1754322</span> <span class="o">-</span><span class="mf">0.61925936</span> <span class="mf">0.12707934</span> <span class="mf">0.33790576</span> <span class="mf">0.9590525</span> <span class="o">-</span><span class="mf">1.0039365</span> <span class="mf">1.2138838</span> <span class="o">-</span><span class="mf">0.15244572</span> <span class="mf">1.3892341</span> <span class="o">-</span><span class="mf">0.2408304</span> <span class="o">-</span><span class="mf">0.41973415</span> <span class="o">-</span><span class="mf">0.9122008</span> <span class="mf">0.61534476</span> <span class="o">-</span><span class="mf">1.3473209</span> <span class="mf">1.8957467</span> <span class="mf">0.54428715</span> <span class="o">-</span><span class="mf">0.45334002</span> <span class="o">-</span><span class="mf">0.46586785</span> <span class="mf">0.9365548</span> <span class="mf">0.7735351</span> <span class="mf">0.020367475</span> <span class="mf">0.03640651</span> <span class="mf">0.6072077</span> <span class="mf">0.2598248</span> <span class="o">-</span><span class="mf">0.60497457</span> <span class="mf">0.74164164</span> <span class="o">-</span><span class="mf">1.4986299</span> <span class="mf">0.030030286</span> <span class="mf">1.0310581</span> <span class="o">-</span><span class="mf">0.7985864</span> <span class="mf">0.59369475</span> <span class="mf">5.3009334</span> <span class="o">-</span><span class="mf">0.26436043</span> <span class="o">-</span><span class="mf">1.0086688</span> <span class="mf">0.69724923</span> <span class="o">-</span><span class="mf">0.082101144</span> <span class="mf">0.609409</span> <span class="o">-</span><span class="mf">0.4504542</span> <span class="o">-</span><span class="mf">0.57361007</span> <span class="o">-</span><span class="mf">0.43234673</span> <span class="o">-</span><span class="mf">0.621053</span> <span class="o">-</span><span class="mf">1.3142335</span> <span class="o">-</span><span class="mf">1.2885888</span> <span class="o">-</span><span class="mf">0.29704484</span> <span class="mf">0.16729134</span> <span class="o">-</span><span class="mf">0.76317424</span> <span class="mf">1.2080128</span> <span class="mf">0.24425012</span> <span class="o">-</span><span class="mf">0.3169634</span> <span class="mf">0.9270621</span> <span class="mf">1.0773871</span> <span class="o">-</span><span class="mf">0.09211676</span> <span class="mf">4.2189116</span> <span class="mf">1.1267253</span> <span class="o">-</span><span class="mf">1.2751623</span> <span class="o">-</span><span class="mf">0.04176733</span> <span class="o">-</span><span class="mf">1.0876625</span> <span class="o">-</span><span class="mf">0.19441187</span> <span class="mf">0.6124146</span> <span class="o">-</span><span class="mf">0.5224489</span> <span class="o">-</span><span class="mf">1.346519</span> <span class="o">-</span><span class="mf">0.129513</span> <span class="o">-</span><span class="mf">0.12585206</span> <span class="mf">0.9263705</span> <span class="o">-</span><span class="mf">1.6089619</span> <span class="o">-</span><span class="mf">1.5251873</span> <span class="mf">1.0640423</span> <span class="mf">1.1027105</span> <span class="o">-</span><span class="mf">0.5490974</span> <span class="o">-</span><span class="mf">0.85569364</span> <span class="o">-</span><span class="mf">1.1080054</span> <span class="mf">0.9023686</span> <span class="o">-</span><span class="mf">1.0494307</span> <span class="o">-</span><span class="mf">0.28588632</span> <span class="o">-</span><span class="mf">0.4288576</span> <span class="o">-</span><span class="mf">0.72663045</span> <span class="mf">1.7789608</span> <span class="mf">2.239715</span> <span class="mf">0.8199781</span> <span class="mf">0.4134441</span><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Memory usage : 110 MB
CPU usage : 100%</p>
<p>Ok we have something - <strong>345 ms per token</strong>. Makes sense, since it is an indirect non-native form of calling what is the first test of cpp&hellip; except as a shared library via Golang. So what about natives?</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9