diff options
author | edef <edef@unfathomable.blue> | 2022-05-02 01:23:08 +0000 |
---|---|---|
committer | edef <edef@unfathomable.blue> | 2022-05-02 01:23:08 +0000 |
commit | b27d8f87d4689aea63834b59629cccee1410b859 (patch) | |
tree | 0d9012f4f4f64beb3e21af8e8f05ffcff484ee34 | |
parent | b3366c335d978b1485c83784a350c17c0d02d9a3 (diff) | |
download | unf-legacy-b27d8f87d4689aea63834b59629cccee1410b859.tar.zst |
ripple/fossil/chunker: eliminate indexing and bounds checks
This improves performance by ~12%. Change-Id: I5612b624da77b138fcfb44cbb439b0106580ed70
-rw-r--r-- | ripple/fossil/src/chunker/mod.rs | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/ripple/fossil/src/chunker/mod.rs b/ripple/fossil/src/chunker/mod.rs index 8dcf796..9172a15 100644 --- a/ripple/fossil/src/chunker/mod.rs +++ b/ripple/fossil/src/chunker/mod.rs @@ -38,27 +38,38 @@ impl<'a> Iterator for Chunker<'a> { return Some(mem::take(&mut self.buffer)); } - let bytes = self - .buffer - .iter() - .cloned() - .enumerate() - .take(MAX_CHUNK_SIZE) - .skip(MIN_CHUNK_SIZE); + let bytes = self.buffer.iter().take(MAX_CHUNK_SIZE).skip(MIN_CHUNK_SIZE); let mut hasher = buz::Rolling::<WINDOW_SIZE>::from_slice(&self.buffer[..MIN_CHUNK_SIZE]); let chunk; - for (idx, byte) in bytes { + for byte in bytes { let buz::Hash(x) = hasher.sum(); if x % DISCRIMINATOR == DISCRIMINATOR.wrapping_sub(1) { // split point - (chunk, self.buffer) = self.buffer.split_at(idx); + (chunk, self.buffer) = unsafe { + // SAFETY: `byte` is in bounds of `self.buffer`, so + // computing `idx` is safe, and `idx` is in bounds + let origin = self.buffer.as_ptr(); + let ptr = byte as *const u8; + let idx = ptr.offset_from(origin) as usize; + ( + self.buffer.get_unchecked(..idx), + self.buffer.get_unchecked(idx..), + ) + }; return Some(chunk); } - hasher.push(byte); + hasher.push(*byte); } - (chunk, self.buffer) = self.buffer.split_at(MAX_CHUNK_SIZE.min(self.buffer.len())); + (chunk, self.buffer) = unsafe { + // SAFETY: `mid` is clamped to `self.buffer.len()` + let mid = MAX_CHUNK_SIZE.min(self.buffer.len()); + ( + self.buffer.get_unchecked(..mid), + self.buffer.get_unchecked(mid..), + ) + }; Some(chunk) } |