HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
c-blake
bu
Nim2022–2026
c-blake / bu

bu

B)asic|But-For U)tility Code/Programs (in Nim & Often Unix/POSIX/Linux Context)

4Distinct people
42Mentions
0Explicit recommenders
77GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

B)asic|But-For U)tility Code/Programs (in Nim & Often Unix/POSIX/Linux Context)

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 1:49:46 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year42 dated mentions

Observed mentions: 2022-11-11 18:14:09 UTC to 2026-10-06 21:45:02 UTC.

0510152022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20222023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 17 mentions; 0 submissions, 17 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 10 mentions; 0 submissions, 10 comments20242025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 10 mentions; 0 submissions, 10 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC17017
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC10010
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC10010
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC404

What Hacker News says

42 sources
This is basically the philosophy of https://github.com/c-blake/bu/blob/main/doc/tim.md , but it uses a somewhat fancier estimator of the minimum than the sample min of dt's (which in some sense is guaranteed to be "a little" high). There are other benchmarking points in that document about measurement footguns that can arise from targeting a specific duration like the 200..400ms of TFA with an easy but careless problem scale-up (like the Ben Hoyt example of footnote 4). With that tool, in user space with just CPU freq pinning, I routinely see CPU bound times that are stable to single digit microseconds month to month on the same machine and see 0.01% to 0.2% effects on 10ms scale activity (yes, 1..20 bps) and the reported uncertainty usually captures the variation all right, but the distribution is not really Gaussian/Normal and instead h
Read the rest
as more shape parameters and/or you would want a 95% CI or some such as mentioned elsethread here.
In Benchmark in Milliseconds
Something Dan does not observe in his article (perhaps Jamie does elsewhere? edit: or even Dan elsewhere) is that the same problem which makes the memory latency benchmark unrealistic (or at least misleading) often impacts hash table lookup benchmarks as mentioned at https://github.com/c-blake/bu/blob/main/doc/memlat.md and probably many other benchmarks. Essentially, CPU work prediction/speculative execution has become so good that much care is often required to measure latency rather than reciprocal throughput. This all started in the 1990s (or probably earlier with Cray), but I guess there's been an ongoing educational failure/oversimplification tendency. Of course, throughput at one "level of work" is often latency at a higher level (like command-to-command execution, for example). So, "what matters" might be throughput or "latency
Read the rest
". It all depends. :-) People often fiddle with such semantics to market methods, products, ideas, ... and marketing is often at cross purposes with understanding.
In Bad benchmarks and evals: Senior SWE-Bench, napkin math, and winter tires
Yeah. The Flask web-page prototype was indeed in Python. (The prequel shirt was Go.) { Also, it was my own Py version which I mostly did in case anyone wanted to actually run the thing after such interest was expressed on this thread. :-) } I already said regular devs and LLMs can both gen copy-pasta. That said, being "mostly" a Python dev, asking some LLM to translate to bash for him seems even more likely to me. Only he or those close to him knows for sure. You & I cannot settle it here conclusively (as also said). I also noted from the video that the ♥s (hearts) worked on whatever version of bash he tested with though it failed for me (which is why I wrote that Python). And his terminal title bar is switching between `tput` and `bc` and such meaning that what he was demoing was not some Python script. ¯\_(ツ)_/¯ EDIT: Ah..another
Read the rest
resolution of the hearts is to not run in an LC_ALL=C environment. Oops! `LC_ALL=en_US.UTF-8 bash ..` fixed it. Oh well, I think the Python script is nicer in almost every way. E.g., you could |head -n60 and send it to a line printer/dot matrix reminiscent of the 1980s computers he shows in the video, although your printer driver would have to strip the color escapes with a `sed` or maybe https://github.com/c-blake/bu/blob/main/noc.nim. ;-)
In Decoding the obfuscated bash script on a Uniqlo t-shirt
One of the coolest tricks is using tcc to compile "on demand." This allows you to use a compiled language like Nim for scripting, with almost no noticeable performance difference compared to interpreted languages. #!/usr/bin/env -S nim r --cc:tcc -d:useMalloc --verbosity:0 --hints:off --tlsEmulation:on --passL:-lm echo "Hello from Nim via TCC!" Here's a comparison (bash script at [1]) of a minimal binary compiled this way with different interpreters. First line is the noise. Measured by tim[2] written by @cb321. 1.151 +- 0.028 ms (AlreadySubtracted)Overhead 1.219 +- 0.037 ms bash -c exit 2.498 +- 0.040 ms fish --no-config --private -c exit 1.682 +- 0.058 ms perl -e 'exit 0' 1.621 +- 0.043 ms gawk 'BEGIN{exit 0}' 15.8 +- 2.2 ms python3 -c 'exit(0)' 20.0 +- 5.7 ms node -e 'process.exit(0)
Read the rest
' -2.384 +- 0.041 ms tcc -run x.c 153.2 +- 4.6 ms nim r --cc:tcc x.nim 164.5 +- 1.2 ms nim r --cc:tcc -d:release x.nim Measured on a laptop without any care to clean the environment, except turning the performance governor. Even with `-d:release` compiling nim code is comparable. The fact that tcc compilation cycle measures negative here is a nice punchline. [1]: https://gist.github.com/ZoomRmc/58743a34d3bb222aa5ec02a5e2b6... [2]: https://github.com/c-blake/bu/blob/main/doc/tim.md
In Tiny C Compiler
Haven't checked graalvm in a long time. So, I got graalvm-jdk-25.0.1+8.1 for x86_64. It's a lot faster than Julia, and maybe 43ms is not slow in "human terms", but it's still pretty slow compared to some other competition. This was for a helloworld.jar [1]. On my laptop (i7-1370P, p-cores) using tim[2]: $ tim "awk '{}'</n" 'tcc -run /tmp/true.c' 'perl</n' 'py2</n' 'py3</n' 'java -jar helloworld.jar>/n' 97.5 +- 1.5 μs (AlreadySubtracted)static dash Overhead 94.9 +- 3.2 μs awk '{}'</n 376.7 +- 4.6 μs tcc -run /tmp/true.c 525.3 +- 2.7 μs perl</n 3627.7 +- 6.0 μs py2</n 6803 +- 11 μs py3</n 42809 +- 71 μs java -jar helloworld.jar>/n Also, probably there is some way to tune this, but it used over 128 MiB of RSS. [1]: https://github.com/jarirajari/helloworld [2]: https://github.com/c-blake/bu/bl
Read the rest
In 2026: The Year of Java in the Terminal?
Once you have a little frecency command-line utility like https://github.com/c-blake/adix/blob/master/util/lfreq.nim (inspired by this very HN thread!) and then either fzf, vip (https://github.com/c-blake/bu/blob/main/doc/vip.md), or whatever, the essence of the idea is really just two lines of Zsh code (https://github.com/c-blake/bu/blob/main/doc/vip.md#combining...). It's only a couple dozen more to have a more robust/complete system, though with shared-across-shells PWD histories and long-term saving somewhere with lock files. As another example of why a simple CL utility for frecency alone is nice, you can basically replicate https://github.com/kantord/frecenfile with a shell 1-liner: git log --pretty=format: --name-only | tac | sed '/^$/d' | lfreq -n9 -o.999 In a little timing test I did this morning, that was about 270X faster
Read the rest
than the git log itself on the Linux kernel (61 seconds to git log, but only 227 ms to `lfreq` it). Besides all that, there's also the distributed-with-Zsh `cdr` (`man zshcontrib` or similar to read all about that).
In Zoxide: A Better CD Command
It's 10x slower than a more specialized command [1] for me, but adding recursion only requires adding one extra asterisk (`**` instead of `*`) and maybe a D if you want to include dot files or triple star if you want to follow symlinks: $ date; print -rl -- **(om[1].D);date; newest -n4 -r0 $HOME Wed Sep 17 12:48:53 EDT 2025 .config/mozilla/firefox/p9/bounce-tracking-protection.sqlite Wed Sep 17 12:49:25 EDT 2025 /u/p9/.config/mozilla/firefox/p9/permissions.sqlite /u/p9/.config/zsh/history /u/p9/.config/mozilla/firefox/p9/places.sqlite-wal /u/p9/.config/mozilla/firefox/p9/bounce-tracking-protection.sqlite *newest -n4 -r0 $HOME Time: 1.882365 (u) + 1.318166 (s)=3.215131 (99%) mxRSS 139 MiB Not sure how to change to get most recent 4 or whatever in the Zsh style (since, you know, that'd be 10x slower
Read the rest
In GNU Midnight Commander
There hasn't been a ton of benchmark comparisons. From memory, on what remains in examples/: The cligen/dents stuff is faster than anything not so enabled with a new kernel call and some perf stuff mentioned right in the comments there, but Linux has moved to blocking installing syscalls from modules. I've timed gl/grls against ripgrep favorably, but it's obviously a very simple pattern subcase. Mostly those were to demo cligen/procpool. examples/cols was faster than awk or xsv for me (which has really moved to https://github.com/c-blake/bu now along with several others like `rp` - which is kind of a "concept piece" showing that any command-line is kind of a "language" already and with just a little codegen magic you can beat awk at most of its own games: https://github.com/c-blake/bu/blob/main/doc/rp.md). Some subthread in one of the h
Read the rest
undreds of closed issue threads got into a comparison of dups and jdupes ( https://github.com/c-blake/cligen/issues/99#issuecomment-485... ) where Jody shows up. I mean, in my test cases dups fared well, but on what many would call the "boring non-IO bound case". For IO bound cases things rapidly depend a lot on your host OS & devices. I should say that "the point" of most of these things was not caffeine-fueled rage optimization, but more to show how easy it is to get performance & functionality out of Nim. Almost all are much smaller programs (perhaps with many fewer features) than their competing programs. But such catering to The Unix Philosophy felt like it fit well with a CLI toolkit. { Even sys_batch is like a 30 lines of C virtual machine for inside Linux instead of untold 10s of thousands for eBPF & IO uring. While porting to other arches would be more, that 30 lines could probably stay the same. }
In Cligen: A Native API-Inferred Command-Line Interface Generator for Nim
This is a good set of slides. Dan is a good guy. There are a few nits I would pick. Sqrt(N) convergence comes from independence not normality -- based on independence => linearity of variance. { So, N IID samples of any distribution have a sum with N times higher variance, but then dividing by N you et sqrt(N). } There is, of course, a higher order relationship between the variance / "scale^2" of the distro and its tails which statisticians refer to as "shape". He later goes on to mention the dependence problem, though, and the minimum dt solution that, relied upon by, e.g., https://github.com/c-blake/bu/blob/main/doc/tim.md. So, it's all good. He may have covered it in voice, even. He also mentions the Sattolo used by https://github.com/c-blake/bu/blob/main/doc/memlat.md to do his memory latency measurements. One weird thing was
Read the rest
how he said because of 1 byte/cycle is 4GB/s things are "easily CPU bound" while I feel like I've been "fighting The Memory Wall for at least 3 decades now..." even just from super-scalar CPUs, but he later does some vectorization stuff. That more relates to what calcs you are doing, of course, but high bandwidth memory is a big part of what nVidia is selling.
In Algorithms for Modern Processor Architectures
Some data in support of @soraminazuki (who makes good points throughout this thread) on an i7-1370P linux laptop running Linux 6.15.7: $ tim 'bash -lic logout' 'zsh -lic logout' 55.3 +- 3.7 μs (AlreadySubtracted)Overhead 7454 +- 26 μs bash -lic logout 7934 +- 39 μs zsh -lic logout (Using https://github.com/c-blake/bu/blob/main/doc/tim.md) About 20,000 entries in the Zsh history slowing it a little. All completion activated (but zcompile'd, along with a very large digraphs.zwc). I think most would not be troubled by taking 1.06X longer, though, especially at this 8 ms scale and for interactive session initiation. Note this test upper bounds Time To First Prompt { a different "TTFP" from Time To First Plot ;-) }, since it also exits as part of the `-c`.
In Speeding up my ZSH shell
You seem to misunderstand @andersa's point which I think is well expressed - it doesn't matter if the indices are randomized if the CPU can pre-fetch what they will be. The power of CPU speculative execution to hide latency can be quite surprising the first time you see it. This is a very small Nim program to demonstrate for "show me the code" and "it must just not be 'random enough'!" skeptics: https://github.com/c-blake/bu/blob/main/memlat.nim It uses the exact dependency idea @andersa mentions of a random cycle of `x[i] = i` that others else-sub-thread say some CPUs these days are smart enough to "see through". On Intel CPUs I have, the dependency makes things 12x slower at the gigabyte scale (DIMMs). EDIT: This same effect makes many a naive hash table microbenchmark { e.g., `for key in keys: lookup(key)` } unrepresentative of perf
Read the rest
ormance in real programs where each `key` is often not speculatively pre-computable.
In How much slower is random access, really?
While some people here are citing 10% as "large" and 1% as "normal", there are optimizations like partial inlining of doubly recursive Fibonacci that can reduce the actual work (and so also time) exponentially (factors >10X for double-digit arguments or 1000s of %, technically exponential in the difference of the recursion depth, not the problem size [1]). C compilers can also be very finicky about their code inlining metrics. So, whether that enormous speed-up is realized can be very sensitive to the shape of your code. So, while part of the problem is definitely that CPUs have gotten quite fancy/complex, another aspect is that compilers "beyond -O0 or -O1" have also gotten fancy/complex. The article here, while good & worth reading, is also but one of many examples of how two complex things interacting can lead to very surprising resul
Read the rest
ts (and this is true outside of computing). People have a rather strong tendency to oversimplify -- no matter how many times this lesson shows up. EDIT: Also, the article at least uses two CPUs, Intel & Apple M1 and two compilers (gcc & clang), but there are realistic deployment scenarios across many more generations/impls of Intel, AMD, and ARM and probably other compilers, too. So, it only even samples a small part of the total complexity. Also, if you want to be more scientific, esp. for differences like "1.01X" then time measurements should really have error bars of some kind (either std.dev of the mean or maybe better for a case like this std.dev of the min[2]) and to minimize those measurement errors you probably want CPU core affinity scheduling in the OS. [1] https://stackoverflow.com/questions/360748/computational-com... [2] https://github.com/c-blake/bu/blob/main/doc/tim.md
In Performance of the Python 3.14 tail-call interpreter
Modern CPUs (with all their buffers & caches & predictor warm-ups & spin-ups) can make benchmarking really tricky unless you have a very specific workload in mind and even then it requires care (like looking at both the edge of[1] and full timing distributions[2] for best-case, average/median/typical case, worst case analysis, etc.). Briefly, the number of ways to get (un)lucky has proliferated over the decades, as has the variety of deployment platforms. Given the depth of that rabbit hole, as writing advice, I might suggest instead motivating via "more space efficient" and refer to exactly fitting fixed-size objects where more general purpose allocators will (usually)¹ waste space to the next power of two. Measuring less dynamic space is also easier (very dynamic space like %cache used can be tricky, though). Controlling scope and pe
Read the rest
dagogy in general is also tricky, but I think this rhetorical advice is common practice and might also double as a way to address your initial misread of the topic. EDIT: he can always do refinements / more analysis in follow up posts/something if this library has any legs for him. [1] https://github.com/c-blake/bu/blob/main/doc/tim.md [2] https://github.com/c-blake/bu/blob/main/doc/edplot.md ¹ Sure, fancy any-size allocators can tack on a histogram of maybe somewhat rounded lg sizes (to economize histo space) and spawn fixed-size object sub-arenas if there are enough of them, say >= enough to fill a VMem page or 2, but this is rare in my experience and also complicates the dispatch to subarenas that you mention above to slightly fancier search. This kind of topic rapidly spirals into allocator-complete discussion and even systems-complete - e.g. a filesystem is largely an allocator with good old MS-DOS FAT being close to a "file is a pool of disk blocks" model.
In Writing a simple pool allocator in C
One reason to have a razor thin custom command shell (perhaps obeying similar conventions across data structures..) is that the parsing for such can be so fast/consistent that you can also use it for benchmarking/perf regression testing with a workload generator. You might also find & record "anomalous" workloads that way or write a little "translator" (some might say "compiler") from a log to such a workload or etc. I have done this for data structures even as fast as integer-keyed hash tables (though in that hyper-fast case you might need to try to measure & subtract off parser-loop/IO dispatch overhead and/or need statistical testing for "actually even different at all", perhaps along the lines of https://github.com/c-blake/bu/blob/main/doc/tim.md).
In Show HN: A portable hash map in C

Showing the 15 most recent of 42 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.