Skip to content

Commit

Permalink
Add in minor optimizations for parsing integers.
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexhuszagh committed Jan 13, 2025
1 parent 44a36be commit 3a5af1d
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
6 changes: 3 additions & 3 deletions lexical-parse-integer/src/algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ macro_rules! algorithm {
let mut value = T::ZERO;
#[allow(unused_variables, unused_mut)]
let mut has_suffix = false;
if cannot_overflow && is_negative {
if T::IS_SIGNED && cannot_overflow && is_negative {
parse_digits_unchecked!(
value,
iter,
Expand All @@ -753,7 +753,7 @@ macro_rules! algorithm {
has_suffix,
true,
);
} if cannot_overflow {
} else if cannot_overflow {
parse_digits_unchecked!(
value,
iter,
Expand All @@ -764,7 +764,7 @@ macro_rules! algorithm {
has_suffix,
true,
);
} else if is_negative {
} else if T::IS_SIGNED && is_negative {
parse_digits_checked!(
value,
iter,
Expand Down
12 changes: 9 additions & 3 deletions lexical-util/src/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,15 +686,21 @@ pub trait Integer:
!self.is_odd()
}

/// Get the maximum number of digits before the slice will overflow.
/// Get the maximum number of digits before the slice could overflow.
///
/// This is effectively the `floor(log(2^BITS-1, radix))`, but we can
/// try to go a bit lower without worrying too much.
#[inline(always)]
fn overflow_digits(radix: u32) -> usize {
// this is heavily optimized for base10 and it's a way under estimate
// that said, it's fast and works.
if radix <= 16 {
// that said, it's fast and works. the radix is **known** at compile
// time so we can optimize this further.
if cfg!(not(feature = "power-of-two")) || radix == 10 {
// NOTE: We generally want powers-of-two since it makes the comparison
// faster (it can just look for the upper bits being set), and luckily
// for radices of 10 we can always use `2 * bytes`.
mem::size_of::<Self>() * 2
} else if radix <= 16 {
mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize
} else {
// way under approximation but always works and is fast
Expand Down

0 comments on commit 3a5af1d

Please sign in to comment.