Write lines into an in-memory buffer before printing to stdout

Running them through an in-memory buffer first produces a 25% speedup
(when tested against a 1.3MB file).
This commit is contained in:
Lily Ballard authored and David Peter committed 2019-01-13 17:35:51 +01:00
1 parent 98311282e5
commit 20694bb628
1 file changed
+31 -21
+31 -21
View File
@@ -76,7 +76,10 @@ impl Byte {
struct Printer<'a> { struct Printer<'a> {
idx: usize, idx: usize,
line: Vec<u8>, /// The raw bytes used as input for the current line.
raw_line: Vec<u8>,
/// The buffered line built with each byte, ready to print to stdout.
buffer_line: Vec<u8>,
stdout: StdoutLock<'a>, stdout: StdoutLock<'a>,
byte_hex_table: Vec<String>, byte_hex_table: Vec<String>,
byte_char_table: Vec<String>, byte_char_table: Vec<String>,
@@ -86,7 +89,8 @@ impl<'a> Printer<'a> {
fn new(stdout: StdoutLock) -> Printer { fn new(stdout: StdoutLock) -> Printer {
Printer { Printer {
idx: 1, idx: 1,
line: vec![], raw_line: vec![],
buffer_line: vec![],
stdout, stdout,
byte_hex_table: (0u8..=u8::max_value()) byte_hex_table: (0u8..=u8::max_value())
.map(|i| format!("{} ", Byte(i).color().paint(format!("{:02x}", i)))) .map(|i| format!("{} ", Byte(i).color().paint(format!("{:02x}", i))))
@@ -123,23 +127,23 @@ impl<'a> Printer<'a> {
fn print_byte(&mut self, b: u8) -> io::Result<()> { fn print_byte(&mut self, b: u8) -> io::Result<()> {
if self.idx % 16 == 1 { if self.idx % 16 == 1 {
let style = COLOR_OFFSET.normal(); let style = COLOR_OFFSET.normal();
write!( let _ = write!(
self.stdout, &mut self.buffer_line,
"│{}{:08x}{}│ ", "│{}{:08x}{}│ ",
style.prefix(), style.prefix(),
self.idx - 1, self.idx - 1,
style.suffix() style.suffix()
)?; );
} }
write!(self.stdout, "{}", self.byte_hex_table[b as usize])?; write!(&mut self.buffer_line, "{}", self.byte_hex_table[b as usize])?;
self.line.push(b); self.raw_line.push(b);
match self.idx % 16 { match self.idx % 16 {
8 => write!(self.stdout, "┊ ")?, 8 => {
0 => { let _ = write!(&mut self.buffer_line, "┊ ");
self.print_textline()?;
} }
0 => self.print_textline()?,
_ => {} _ => {}
} }
@@ -149,42 +153,48 @@ impl<'a> Printer<'a> {
} }
fn print_textline(&mut self) -> io::Result<()> { fn print_textline(&mut self) -> io::Result<()> {
let len = self.line.len(); let len = self.raw_line.len();
if len == 0 { if len == 0 {
return Ok(()); return Ok(());
} }
if len < 8 { if len < 8 {
write!( let _ = write!(
self.stdout, &mut self.buffer_line,
"{0:1$}┊{0:2$}│", "{0:1$}┊{0:2$}│",
"", "",
3 * (8 - len), 3 * (8 - len),
1 + 3 * 8 1 + 3 * 8
)?; );
} else { } else {
write!(self.stdout, "{0:1$}│", "", 3 * (16 - len))?; let _ = write!(&mut self.buffer_line, "{0:1$}│", "", 3 * (16 - len));
} }
let mut idx = 1; let mut idx = 1;
for &b in self.line.iter() { for &b in self.raw_line.iter() {
write!(self.stdout, "{}", self.byte_char_table[b as usize])?; let _ = write!(
&mut self.buffer_line,
"{}",
self.byte_char_table[b as usize]
);
if idx == 8 { if idx == 8 {
write!(self.stdout, "┊").ok(); let _ = write!(&mut self.buffer_line, "┊");
} }
idx += 1; idx += 1;
} }
if len < 8 { if len < 8 {
writeln!(self.stdout, "{0:1$}┊{0:2$}│ ", "", 8 - len, 8)?; let _ = writeln!(&mut self.buffer_line, "{0:1$}┊{0:2$}│ ", "", 8 - len, 8);
} else { } else {
writeln!(self.stdout, "{0:1$}│", "", 16 - len)?; let _ = writeln!(&mut self.buffer_line, "{0:1$}│", "", 16 - len);
} }
self.stdout.write_all(&self.buffer_line)?;
self.line.clear(); self.raw_line.clear();
self.buffer_line.clear();
Ok(()) Ok(())
} }