printer: hand-roll decimal formatting

It seems like a trifle, but if the match frequency is high enough, the
allocation+formatting of line numbers (and columns and byte offsets)
starts to matter. We squash that part of the profile in this commit by
doing our own decimal formatting. I speculate that we get a speed-up
from this by avoiding the formatting machinery and also a possible
allocation.

An alternative would be to use the `itoa` crate, and it is indeed
marginally faster in ad hoc benchmarks, but I'm satisfied enough with
this solution.
This commit is contained in:
Andrew Gallant
2023-09-30 14:16:51 -04:00
parent dd1bc5b898
commit 1659fb9b43
3 changed files with 67 additions and 7 deletions

View File

@@ -24,7 +24,7 @@ use crate::{
stats::Stats,
util::{
find_iter_at_in_context, trim_ascii_prefix, trim_line_terminator,
PrinterPath, Replacer, Sunk,
DecimalFormatter, PrinterPath, Replacer, Sunk,
},
};
@@ -1709,7 +1709,7 @@ impl<'a, M: Matcher, W: WriteColor> PreludeWriter<'a, M, W> {
fn write_line_number(&mut self, line: Option<u64>) -> io::Result<()> {
let Some(line_number) = line else { return Ok(()) };
self.write_separator()?;
let n = line_number.to_string();
let n = DecimalFormatter::new(line_number);
self.std.write_spec(self.config().colors.line(), n.as_bytes())?;
self.next_separator = PreludeSeparator::FieldSeparator;
Ok(())
@@ -1723,7 +1723,7 @@ impl<'a, M: Matcher, W: WriteColor> PreludeWriter<'a, M, W> {
}
let Some(column_number) = column else { return Ok(()) };
self.write_separator()?;
let n = column_number.to_string();
let n = DecimalFormatter::new(column_number);
self.std.write_spec(self.config().colors.column(), n.as_bytes())?;
self.next_separator = PreludeSeparator::FieldSeparator;
Ok(())
@@ -1736,7 +1736,7 @@ impl<'a, M: Matcher, W: WriteColor> PreludeWriter<'a, M, W> {
return Ok(());
}
self.write_separator()?;
let n = offset.to_string();
let n = DecimalFormatter::new(offset);
self.std.write_spec(self.config().colors.column(), n.as_bytes())?;
self.next_separator = PreludeSeparator::FieldSeparator;
Ok(())