noamteyssier
noamteyssier on Hacker News
Good question! I just added that comparison and the rust uutils coreutils port is significantly faster than the standard coreutils.
I think this could potentially really reduce the amount of memory required - especially in cases where there is a lot of repetitive prefixes.
Would be interesting to try this out
I think you'd still need to go through that if you were really optimizing both `sort` and `uniq` working with their constraints.
What I'm really optimizing here is the functional equivalent of `sort | uniq -c | sort -n`
yeah that's right - there are trade-offs in doing so as it can require much more memory. So like everything it's an application specific decision
I've added this functionality to `hist-0.1.5` with a benchmark of other tools that do this on the CLI
this looks very interesting and I'd love to add it to the benchmarking! I was interested in trying it but unfortunately got an installation error on my macbook where I'm running the benchmarks:
```
clang \
-g -ggdb -O3 \
-Wall -Wextra -Wpointer-arith \
-D_FORTIFY_SOURCE=2 -fPIE \
mmuniq.c \
-lm \
-Wl,-z,now -Wl,-z,relro \
-o mmuniq
mmuniq.c:1:10: fatal error: 'byteswap.h' file not found
1 | #include <byteswap.h>
| ^~~~~~~~~~~~
1 error generated.
make: ** [mmuniq] Error 1
```
I've actually added a benchmark for this specific task and added `unic` to it.
It may not be the most fair comparison because with these random fastqs I'm generating the vast majority of the input is unique so it could be overloading the cuckoo filter.
Shows up a lot in bioinformatics actually - trying to identify sequences with a specific subsequence (grep) and how many of each unique sequence there are. The number of lines here could be massive (order of 1-10's of GB)
You don't really end up using these results in any specific analysis but it's super helpful for troubleshooting tools or edge-cases.
I've added awk into the benchmarks also!
Yeah I'm using it to serialize the output lines as a TSV. Rust's `println!` is notoriously slow and using `csv` to serialize the output is a nice way to boost throughput
Yes you're right, it's not trying to do what `sort` is doing, it's trying to reproduce the output of `sort | uniq -c | sort -n` which is a more specialized but common task.
But you're right - it will be limited by RAM in a way the unix tools are not.
I did add a test with sort using a larger buffer size to the benchmarks as well.
Thanks for sharing!
You're right that the `cat` is unnecessary - and removing it actually had some marginal gains to the naive solution. I've updated the benchmarks to show this
Cheers
Yeah definitely, it's always a trade-off. I think in many cases where I use it especially the number of unique values is actually not crazy high (much less than the required RAM) and the number of lines
is crazy high.
So in those settings I think it's absolutely worth it
I didn't know that - I've added in buffer size with a fairly large buffer to the benchmarks as well
Cool suggestions! I definitely would be interested in exploring other hash functions for this (and other binf works) so I'll definitely take a look at your stringzilla lib.
Totally agree it's a bit of weird benchmark - it was just the first thing that I thought of to generate a huge amount of lines to test throughput.
There are definitely other benchmarks that we could try as well to test other characteristics as well.
I've actually just added in this `awk` implementation you provided to the benchmarks well.
Cheers!
I think that it's a pretty common use case for text processing - I end up needing to use it a lot in bioinformatics where there is a lot of text processing.
It's great when you quickly need to see what the distribution of classes in an input stream is. This pops up all the time. Like measuring different types of log messages, counting the variants of a field in a csv, finding the most common word or substring, etc.
Posted by
noamteyssier on Thursday October 23, 2025 @12:26PM
from the show-hn dept.
https://github.com/noamteyssier/hist-rs
Was sitting around in meetings yesterday and remembered an old shell script I had to count the number of unique lines in a file. Gave it a shot in rust and with a little bit of (over-engineering)™ I managed to get 25x throughput over the naive approach using coreutils as well as improve over some existing tools.Some notes on the improvements:1. using csv (serde) for writing leads to some big...
Posted by
noamteyssier on Wednesday October 22, 2025 @06:26PM
from the github.com dept.
Was sitting around in meetings today and remembered an old shell script I had to count the number of unique lines in a file. Gave it a shot in rust and with a little bit of (over-engineering)™ I managed to get 25x throughput over the naive approach using coreutils as well as improve over some existing tools.
Some notes on the improvements:
1. using csv (serde) for writing leads to some big gains
2. arena allocation of incoming keys + storing references in the hashmap instead of storing owned values heavily reduced the number of allocations and improves cache efficiency (I'm guessing, I did not measure).
There are some regex functionalities and some table filtering built in as well.
happy hacking