Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Use buffered stdout to reduce write sys calls.
This simple change yielded the biggest performance gain.
Use
for_byte_record_with_terminator
from thebstr
crate.This is to minimize the per line copying needed by
BufReader::read_until
. Thecut_fields
andcut_fields_delimiter
functions usedread_until
to iterate over lines. That required copying each input line to the line buffer. Withfor_byte_record_with_terminator
copying is minimized as it calls our closure with a reference to BufReader's buffer most of the time. It needs to copy (internally) only to process any incomplete lines at the end of the buffer.Re-write
Searcher
to usememchr
.Switch from the naive implementation to one that uses
memchr
.Rewrite
cut_bytes
almost entirely.This was already well optimized. The performance gain in this case is not from avoiding copying. In fact, it needed zero copying whereas new implementation introduces some copying similar to
cut_fields
described above. But the occasional copying cost is more than offset by the use of the very fastmemchr
insidefor_byte_record_with_terminator
. This change also simplifies the code significantly. Removed thebuffer
module.Benchmarks
$ hyperfine -w3 "./target/release/cut -c2-4,8 test-large.txt" "cut -c2-4,8 test-large.txt"
Before
After
$ hyperfine -w3 "./target/release/cut -f2-4,8 -d' ' test-large.txt" "cut -f2-4,8 -d' ' test-large.txt"
Before
After
hyperfine -w3 "./target/release/cut -f2-4,8 -d' ' --output-delimiter=- test-large.txt" "cut -f2-4,8 -d' ' --output-delimiter=- test-large.txt"
Before
After