From e25bd1fcf3c330e0ca266c542a5200b4b7d0e614 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 14 Feb 2020 16:52:07 +1100 Subject: [PATCH] Tweak LEB128 reading some more. PR #69050 changed LEB128 reading and writing. After it landed I did some double-checking and found that the writing changes were universally a speed-up, but the reading changes were not. I'm not exactly sure why, perhaps there was a quirk of inlining in the particular revision I was originally working from. This commit reverts some of the reading changes, while still avoiding `unsafe` code. I have checked it on multiple revisions and the speed-ups seem to be robust. --- src/libserialize/leb128.rs | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/libserialize/leb128.rs b/src/libserialize/leb128.rs index 1fe6a309e9650..8045c5c1fae89 100644 --- a/src/libserialize/leb128.rs +++ b/src/libserialize/leb128.rs @@ -1,7 +1,31 @@ +#[cfg(target_pointer_width = "32")] +const USIZE_LEB128_SIZE: usize = 5; +#[cfg(target_pointer_width = "64")] +const USIZE_LEB128_SIZE: usize = 10; + +macro_rules! leb128_size { + (u16) => { + 3 + }; + (u32) => { + 5 + }; + (u64) => { + 10 + }; + (u128) => { + 19 + }; + (usize) => { + USIZE_LEB128_SIZE + }; +} + macro_rules! impl_write_unsigned_leb128 { ($fn_name:ident, $int_ty:ident) => { #[inline] pub fn $fn_name(out: &mut Vec, mut value: $int_ty) { + // A `loop` is faster than a `for` loop for writing. loop { if value < 0x80 { out.push(value as u8); @@ -28,17 +52,17 @@ macro_rules! impl_read_unsigned_leb128 { let mut result = 0; let mut shift = 0; let mut position = 0; - loop { + // A `for` loop is faster than a `loop` for reading. + for _ in 0..leb128_size!($int_ty) { let byte = slice[position]; position += 1; + result |= ((byte & 0x7F) as $int_ty) << shift; if (byte & 0x80) == 0 { - result |= (byte as $int_ty) << shift; - return (result, position); - } else { - result |= ((byte & 0x7F) as $int_ty) << shift; + break; } shift += 7; } + (result, position) } }; }