Skip to content

Commit

Permalink
perf: use shifting to construct primitive integers (#379)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicceboy authored Nov 26, 2024
1 parent 87ae611 commit cec3747
Showing 1 changed file with 21 additions and 8 deletions.
29 changes: 21 additions & 8 deletions src/types/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,11 +511,18 @@ macro_rules! integer_type_impl {
return Err(crate::error::DecodeError::integer_overflow(<$t1>::BITS, codec));
}

let mut array = [0u8; BYTE_SIZE];
let pad = if input[0] & 0x80 == 0 { 0 } else { 0xff };
array[..BYTE_SIZE - input.len()].fill(pad);
array[BYTE_SIZE - input.len()..].copy_from_slice(input);
Ok(Self::from_be_bytes(array))
// Use shifting to directly construct the primitive integer types
// Convert first byte with sign extension
let mut result = (input[0] as $t1) << (BYTE_SIZE - 1) * 8;
result >>= (BYTE_SIZE - input.len()) * 8;
// // Handle remaining bytes
// Add remaining bytes
for (i, &byte) in input.iter().skip(1).enumerate() {
result |= (byte as $t1) << (8 * (input.len() - 2 - i));
}

Ok(result)

}

#[inline(always)]
Expand Down Expand Up @@ -622,9 +629,15 @@ macro_rules! integer_type_impl {
return Err(crate::error::DecodeError::integer_overflow(<$t1>::BITS, codec));
}

let mut array = [0u8; BYTE_SIZE];
array[BYTE_SIZE - input.len()..].copy_from_slice(input);
Ok(Self::from_be_bytes(array))
// Use shifting to directly construct the primitive integer types
let mut result: $t1 = 0;
// Calculate how many positions to shift each byte
let start_shift = (input.len() - 1) * 8;
for (i, &byte) in input.iter().enumerate() {
let shift = start_shift - (i * 8);
result |= (byte as $t1) << shift;
}
Ok(result)
}

// Getting signed bytes of an unsigned integer is challenging, because we don't want to truncate the value
Expand Down

0 comments on commit cec3747

Please sign in to comment.