From 62b8f39f8fed119223879049a3843b9bfe07df79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lena=20Hellstr=C3=B6m?= Date: Fri, 22 Oct 2021 14:47:44 +0200 Subject: [PATCH] Optimize performance of decoding u8 arrays --- src/de/impls.rs | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/de/impls.rs b/src/de/impls.rs index 9a738ed..2729878 100644 --- a/src/de/impls.rs +++ b/src/de/impls.rs @@ -10,6 +10,7 @@ use crate::{ error::{DecodeError, IntegerType}, }; use core::{ + any::TypeId, cell::{Cell, RefCell}, num::{ NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128, @@ -384,7 +385,7 @@ impl<'a, 'de: 'a> BorrowDecode<'de> for &'a str { impl Decode for [T; N] where - T: Decode + Sized, + T: Decode + Sized + 'static, { fn decode(mut decoder: D) -> Result { if !D::C::SKIP_FIXED_ARRAY_LENGTH { @@ -397,12 +398,24 @@ where } } - let result = - super::impl_core::collect_into_array(&mut (0..N).map(|_| T::decode(&mut decoder))); + if TypeId::of::() == TypeId::of::() { + let mut buf = [0u8; N]; + decoder.reader().read(&mut buf)?; + let ptr = &mut buf as *mut _ as *mut [T; N]; - // result is only None if N does not match the values of `(0..N)`, which it always should - // So this unsafe should never occur - result.unwrap() + // Safety: we know that T is a u8, so it is perfectly safe to + // translate an array of u8 into an array of T + let res = unsafe { ptr.read() }; + core::mem::forget(buf); + Ok(res) + } else { + let result = + super::impl_core::collect_into_array(&mut (0..N).map(|_| T::decode(&mut decoder))); + + // result is only None if N does not match the values of `(0..N)`, which it always should + // So this unsafe should never occur + result.unwrap() + } } }