uutils/coreutils — pull request #345 by polyphemus (2014-07-09 10:48:30+00:00)
Title: Rewrite bytes cutting for cut

A rewrite the bytes cutting implementation for cut.

The previous version relied on BufferedReader's `Buffer::read_until(&mut self, byte: u8) -> IoResult>` which did at least one allocation for each line read. This version buffers by itself and no longer has to search for newline bytes twice (once by `read_until()`).

Overall this is a more efficient implementation: the bytes cutting functionality now out performs GNU by a significant margin. For finite ranges it is about 1.5 times faster than GNU and for infinite ranges 2 to 2.3 times faster.

ranges=4-6,3-8,20-30,15-25,23,6
$ perf stat -r 10 ../build/cut -b $ranges `find /boot -type f -readable` >/tmp/uucut
...
0.118819192 seconds time elapsed ( +- 0.09% )
$ perf stat -r 10 cut -b $ranges `find /boot -type f -readable` >/tmp/gcut
...
0.180773381 seconds time elapsed ( +- 0.05% )
$ perf stat -r 10 ./old_cut -b $ranges `find /boot -type f -readable` >/tmp/old_uucut
...
0.225963752 seconds time elapsed ( +- 1.18% )

ranges=1
NEW: 0.109852214 seconds time elapsed ( +- 0.38% )
GNU: 0.166222878 seconds time elapsed ( +- 0.05% )
OLD: 0.216947847 seconds time elapsed ( +- 0.20% )

ranges=1-
NEW: 0.134443475 seconds time elapsed ( +- 0.20% )
GNU: 0.308440640 seconds time elapsed ( +- 0.26% )
OLD: 0.247420434 seconds time elapsed ( +- 0.68% )

ranges=-4097
NEW: 0.132355005 seconds time elapsed ( +- 0.12% )
GNU: 0.305371921 seconds time elapsed ( +- 0.17% )
OLD: 0.244278895 seconds time elapsed ( +- 0.10% )