From 331f89073b84f75706875d57efefbf9aee2d9799 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Wed, 26 Jun 2019 19:58:05 +0200 Subject: [PATCH 1/2] Use lookup tables safely. The performance difference is below 1% --- src/deflate/symbol.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/deflate/symbol.rs b/src/deflate/symbol.rs index 5ecaffe..c8df5bb 100644 --- a/src/deflate/symbol.rs +++ b/src/deflate/symbol.rs @@ -212,7 +212,7 @@ impl Decoder { } length_code => { let (base, extra_bits) = - unsafe { *LENGTH_TABLE.get_unchecked(length_code as usize - 257) }; + LENGTH_TABLE[length_code as usize - 257]; let extra = reader.read_bits_unchecked(extra_bits); Symbol::Share { length: base + extra, @@ -227,7 +227,7 @@ impl Decoder { R: io::Read, { let decoded = self.distance.decode_unchecked(reader) as usize; - let (base, extra_bits) = unsafe { *DISTANCE_TABLE.get_unchecked(decoded) }; + let (base, extra_bits) = DISTANCE_TABLE[decoded]; let extra = reader.read_bits_unchecked(extra_bits); base + extra } From 659ffd8f4226a5882fd7e4fc4491ea494becb660 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Wed, 26 Jun 2019 21:05:35 +0200 Subject: [PATCH 2/2] Convert all remaining unsafe lookups to safe. No performance difference compared to previous commit. --- src/huffman.rs | 10 ++++------ src/lz77/default.rs | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/huffman.rs b/src/huffman.rs index 28d6d6d..f3e2f17 100644 --- a/src/huffman.rs +++ b/src/huffman.rs @@ -99,9 +99,7 @@ impl Builder for DecoderBuilder { ); return Err(io::Error::new(io::ErrorKind::InvalidData, message)); } - unsafe { - *self.table.get_unchecked_mut(i) = value; - } + self.table[i] = value; } Ok(()) } @@ -137,11 +135,11 @@ impl Decoder { R: io::Read, { let code = reader.peek_bits_unchecked(self.eob_bitwidth); - let mut value = unsafe { *self.table.get_unchecked(code as usize) }; + let mut value = self.table[code as usize]; let mut bitwidth = (value & 0b1_1111) as u8; if bitwidth > self.eob_bitwidth { let code = reader.peek_bits_unchecked(self.max_bitwidth); - value = unsafe { *self.table.get_unchecked(code as usize) }; + value = self.table[code as usize]; bitwidth = (value & 0b1_1111) as u8; if bitwidth > self.max_bitwidth { reader.set_last_error(invalid_data_error!("Invalid huffman coded stream")); @@ -216,7 +214,7 @@ impl Encoder { symbol, self.table.len() ); - unsafe { self.table.get_unchecked(symbol as usize) }.clone() + self.table[symbol as usize].clone() } pub fn used_max_symbol(&self) -> Option { self.table diff --git a/src/lz77/default.rs b/src/lz77/default.rs index d00dd94..8738b92 100644 --- a/src/lz77/default.rs +++ b/src/lz77/default.rs @@ -165,7 +165,7 @@ impl LargePrefixTable { let p2 = prefix[2]; let i = (p0 << 8) + p1; - let positions = unsafe { self.table.get_unchecked_mut(i) }; + let positions = &mut self.table[i]; for &mut (key, ref mut value) in positions.iter_mut() { if key == p2 { let old = *value;