Skip to content

Commit

Permalink
Speed up sum by using reasonable read buffer sizes.
Browse files Browse the repository at this point in the history
Use a 4K read buffer for each of the checksum functions, which seems
reasonable. This improves the performance of BSD checksums on
odyssey1024.txt from 399ms to 325ms on my laptop, and of SysV
checksums from 242ms to 67ms.
  • Loading branch information
resistor committed Jul 25, 2022
1 parent ec9130a commit cd11276
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions src/uu/sum/src/sum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,19 @@ static USAGE: &str = "{} [OPTION]... [FILE]...";
static SUMMARY: &str = "Checksum and count the blocks in a file.\n\
With no FILE, or when FILE is -, read standard input.";

// This can be replaced with usize::div_ceil once it is stabilized
fn div_ceil(a: usize, b: usize) -> usize {
(a + b - 1) / b
}

fn bsd_sum(mut reader: Box<dyn Read>) -> (usize, u16) {
let mut buf = [0; 1024];
let mut blocks_read = 0;
let mut buf = [0; 4096];
let mut bytes_read = 0;
let mut checksum: u16 = 0;
loop {
match reader.read(&mut buf) {
Ok(n) if n != 0 => {
blocks_read += 1;
bytes_read += n;
for &byte in buf[..n].iter() {
checksum = (checksum >> 1) + ((checksum & 1) << 15);
checksum = checksum.wrapping_add(u16::from(byte));
Expand All @@ -40,18 +45,19 @@ fn bsd_sum(mut reader: Box<dyn Read>) -> (usize, u16) {
}
}

let blocks_read = div_ceil(bytes_read, 1024);
(blocks_read, checksum)
}

fn sysv_sum(mut reader: Box<dyn Read>) -> (usize, u16) {
let mut buf = [0; 512];
let mut blocks_read = 0;
let mut buf = [0; 4096];
let mut bytes_read = 0;
let mut ret = 0u32;

loop {
match reader.read(&mut buf) {
Ok(n) if n != 0 => {
blocks_read += 1;
bytes_read += n;
for &byte in buf[..n].iter() {
ret = ret.wrapping_add(u32::from(byte));
}
Expand All @@ -63,6 +69,7 @@ fn sysv_sum(mut reader: Box<dyn Read>) -> (usize, u16) {
ret = (ret & 0xffff) + (ret >> 16);
ret = (ret & 0xffff) + (ret >> 16);

let blocks_read = div_ceil(bytes_read, 512);
(blocks_read, ret as u16)
}

Expand Down

0 comments on commit cd11276

Please sign in to comment.