My attempt to write a simple word counter in rust. Focusing on performance/speed book style text files (not xml, code, html, etc). Currently we are ~1.8-2.1x more performant than wc on very large files, while wc is faster on very small files. Speed parity is at files around 200kb in size.
To be fair, wc is probably more portable and supports a few options that my version doesn't yet.
We are using hyperfine to benchmark vs wc for benchmarking and wc for judging correctness. (Note: that I think wc has a bug with greek letters, a file with εξω βελους returns 3 words with wc, but it should only be 2 I think?!?)
There are a few rust implementations, though currently low_level_buf_reader is our best performing variant.
You should be able to just compile and have it built. You can install it if you'd like.
Benchmarks run on 2019 MBP 2.6 GHz 6-Core Intel Core i7 comparing wc and my low_level_buf_reader version.
| File | File Size | wc Time | ryans_rust_wc Time | Winner | rrwc perf improvement |
|---|---|---|---|---|---|
| "Hello world" | 12 b | 2.0ms | 2.7ms | wc | 0.75 |
| Moby Dick's 1st Chapter | 13 Kb | 2.2ms | 2.7ms | wc | 0.82 |
| Moby Dick Chapters 1-10 | 103 Kb | 2.7ms | 2.9ms | wc | 0.93 |
| Moby Dick Chapters 1-25 | 235 Kb | 3.4ms | 3.2ms | rrwc | 1.06 |
| Moby Dick Chapters 1-50 | 489 Kb | 4.8ms | 3.9ms | rrwc | 1.23 |
| Moby Dick | 1.3 Mb | 9.1ms | 5.8ms | rrwc | 1.58 |
| KJV Bible | 4.3 Mb | 25.0ms | 13.4ms | rrwc | 1.87 |
| 10x KJV Bible | 43.3 Mb | 223.4ms | 107.4ms | rrwc | 2.08 |
| 100x KJV Bible | 432.8 Mb | 2.249s | 1.083s | rrwc | 2.08 |
- Rustc 1.63+ (I think), built and tested on rustc 1.73.0
- Just, if you want to run the just commands. Install instructions by platform.
Run just download-test-texts to download and generate all the texts for benchmarking (5-6Mbg of downloads, close to 500mb once unzipped+generated).
Run just benchmark <version_1> <version_2> to compare two versions with the benchmark script. Currently supported versions are:
wc- the GNU tool- My implementations:
naive- the 2 minute versionlow_level_buf_reader- a low level loop that processes character by character using a bufreader for io. This is the best implementation so far.
- My misfit toys- not trustworthy implementations:
low_level_full_filelow_level_custom_buffernaive_rayonnaive_rayon_big_bufnaive_full_filefull_file_via_buf
Under progress. Use at your own risk (like the whole project, but especially this).
Only supports Mac. Requires installation of Xcode. Requires cargo-instruments. Install with brew install cargo-instruments.
Run just profile-small <version> or just profile-large <version>. wc is not supported for profiling.
- Performance tuning on small files
- unit tests
- Write tests to compare WC and rust output
- pretty graphs
- Make profiling useful and figure it out more
- Test some more obscure-y edge cases - emojis, etc