From a5fce60f36a8d5efc1ee06eb4cf3fbe2c9034074 Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Sun, 6 Mar 2022 20:30:18 +0100 Subject: [PATCH] perf(decode): optimize Vec alloc/resize Avoid calloc overhead of initializing buffer we'll write into Unfortunately requires unsafe Vec::set_len so we can get a mutable ref to the uninit portion of the Vec's buffer --- src/decode.rs | 12 +++++++----- src/lib.rs | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/decode.rs b/src/decode.rs index 527f5e8..67cc58b 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -105,8 +105,7 @@ pub fn decode_engine>( input: T, engine: &E, ) -> Result, DecodeError> { - let mut buffer = Vec::::with_capacity(input.as_ref().len() * 4 / 3); - + let mut buffer = Vec::new(); decode_engine_vec(input, &mut buffer, engine).map(|_| buffer) } @@ -156,11 +155,14 @@ pub fn decode_engine_vec<'e, 'o, E: Engine, T: AsRef<[u8]>>( let starting_output_len = buffer.len(); let estimate = engine.decoded_length_estimate(input_bytes.len()); - let total_len_estimate = estimate - .decoded_length_estimate() + let len_estimate = estimate.decoded_length_estimate(); + let total_len_estimate = len_estimate .checked_add(starting_output_len) .expect("Overflow when calculating output buffer length"); - buffer.resize(total_len_estimate, 0); + buffer.reserve(len_estimate); + unsafe { + buffer.set_len(total_len_estimate); + } let bytes_written; { diff --git a/src/lib.rs b/src/lib.rs index 3ad65b6..bf7f81d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,7 +85,7 @@ variant_size_differences, warnings )] -#![forbid(unsafe_code)] +// #![forbid(unsafe_code)] #![cfg_attr(not(any(feature = "std", test)), no_std)] #[cfg(all(feature = "alloc", not(any(feature = "std", test))))]