diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-01-24 13:32:50 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-01-24 13:32:50 +0100 |
commit | e9fcf9181f21cf7d687131e5aa191beb68a75a8e (patch) | |
tree | a184409916f77746fc24ca7086d4706aaef6dbf5 /openpgp/src | |
parent | a3510fd98f5aabf26ce3d3c76b249090386279c4 (diff) |
openpgp: Optimize drop(Vec<u8>::drain(..n)) in debug mode.
- Similar to Vec<u8>::truncate(_), this operation is very slow in
debug mode due to the dropping of drained elements. Provide an
optimized version in debug mode.
Diffstat (limited to 'openpgp/src')
-rw-r--r-- | openpgp/src/armor.rs | 4 | ||||
-rw-r--r-- | openpgp/src/crypto/aead.rs | 4 | ||||
-rw-r--r-- | openpgp/src/crypto/symmetric.rs | 4 | ||||
-rw-r--r-- | openpgp/src/lib.rs | 19 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 6 | ||||
-rw-r--r-- | openpgp/src/serialize/partial_body.rs | 2 |
6 files changed, 29 insertions, 10 deletions
diff --git a/openpgp/src/armor.rs b/openpgp/src/armor.rs index 5214d4a7..d690bfc5 100644 --- a/openpgp/src/armor.rs +++ b/openpgp/src/armor.rs @@ -1036,7 +1036,7 @@ impl<'a> Read for Reader<'a> { let amount = cmp::min(buf.len(), self.buffer.len()); buf[..amount].copy_from_slice(&self.buffer[..amount]); - self.buffer.drain(..amount); + crate::vec_drain_prefix(&mut self.buffer, amount); (0, amount) } else { @@ -1111,7 +1111,7 @@ impl<'a> Read for Reader<'a> { let copied = cmp::min(buf.len(), self.buffer.len()); buf[..copied].copy_from_slice(&self.buffer[..copied]); - self.buffer.drain(..copied); + crate::vec_drain_prefix(&mut self.buffer, copied); copied } else { diff --git a/openpgp/src/crypto/aead.rs b/openpgp/src/crypto/aead.rs index 35fbd074..a297b999 100644 --- a/openpgp/src/crypto/aead.rs +++ b/openpgp/src/crypto/aead.rs @@ -223,7 +223,7 @@ impl<'a> Decryptor<'a> { if self.buffer.len() > 0 { let to_copy = cmp::min(self.buffer.len(), plaintext.len()); &plaintext[..to_copy].copy_from_slice(&self.buffer[..to_copy]); - self.buffer.drain(..to_copy); + crate::vec_drain_prefix(&mut self.buffer, to_copy); pos = to_copy; if pos == plaintext.len() { @@ -341,7 +341,7 @@ impl<'a> Decryptor<'a> { &plaintext[pos..pos + to_copy] .copy_from_slice(&self.buffer[..to_copy]); - self.buffer.drain(..to_copy); + crate::vec_drain_prefix(&mut self.buffer, to_copy); pos += to_copy; } else { pos += to_decrypt; diff --git a/openpgp/src/crypto/symmetric.rs b/openpgp/src/crypto/symmetric.rs index b6aa799b..fb889dd4 100644 --- a/openpgp/src/crypto/symmetric.rs +++ b/openpgp/src/crypto/symmetric.rs @@ -205,7 +205,7 @@ impl<R: io::Read> io::Read for Decryptor<R> { if self.buffer.len() > 0 { let to_copy = cmp::min(self.buffer.len(), plaintext.len()); &plaintext[..to_copy].copy_from_slice(&self.buffer[..to_copy]); - self.buffer.drain(..to_copy); + crate::vec_drain_prefix(&mut self.buffer, to_copy); pos = to_copy; } @@ -274,7 +274,7 @@ impl<R: io::Read> io::Read for Decryptor<R> { format!("{}", e)))?; &plaintext[pos..pos + to_copy].copy_from_slice(&self.buffer[..to_copy]); - self.buffer.drain(..to_copy); + crate::vec_drain_prefix(&mut self.buffer, to_copy); pos += to_copy; diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs index f1d1506e..0bc4b3d2 100644 --- a/openpgp/src/lib.rs +++ b/openpgp/src/lib.rs @@ -90,6 +90,25 @@ fn vec_truncate(v: &mut Vec<u8>, len: usize) { } } +/// Like `drop(Vec<u8>::drain(..prefix_len))`, but fast in debug +/// builds. +fn vec_drain_prefix(v: &mut Vec<u8>, prefix_len: usize) { + if cfg!(debug_assertions) { + // Panic like v.drain(..prefix_len). + assert!(prefix_len <= v.len(), "prefix len {} > vector len {}", + prefix_len, v.len()); + let new_len = v.len() - prefix_len; + unsafe { + std::ptr::copy(v[prefix_len..].as_ptr(), + v[..].as_mut_ptr(), + new_len); + } + vec_truncate(v, new_len); + } else { + v.drain(..prefix_len); + } +} + // Like assert!, but checks a pattern. // // assert_match!(Some(_) = x); diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 61c12915..1b939c5b 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -895,7 +895,7 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { let n = cmp::min(buf.len(), reserve.len()); &mut buf[..n].copy_from_slice(&reserve[..n]); - reserve.drain(..n); + crate::vec_drain_prefix(reserve, n); return Ok(n); } @@ -1091,7 +1091,7 @@ impl<'a> Transformer<'a> { let n = cmp::min(buf.len(), self.buffer.len()); &mut buf[..n].copy_from_slice(&self.buffer[..n]); - self.buffer.drain(..n); + crate::vec_drain_prefix(&mut self.buffer, n); Ok(n) } } @@ -1809,7 +1809,7 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { let n = cmp::min(buf.len(), reserve.len()); &mut buf[..n].copy_from_slice(&reserve[..n]); - reserve.drain(..n); + crate::vec_drain_prefix(reserve, n); return Ok(n); } diff --git a/openpgp/src/serialize/partial_body.rs b/openpgp/src/serialize/partial_body.rs index 26bb0e14..b85b8b9c 100644 --- a/openpgp/src/serialize/partial_body.rs +++ b/openpgp/src/serialize/partial_body.rs @@ -138,7 +138,7 @@ impl<'a, C: 'a> PartialBodyFilter<'a, C> { // ... from our buffer first... let l = cmp::min(self.buffer.len(), chunk_size); inner.write_all(&self.buffer[..l])?; - self.buffer.drain(..l); + crate::vec_drain_prefix(&mut self.buffer, l); // ... then from other. if chunk_size > l { |