Skip to content

Commit 3a5af1d

Browse files
committed
Add in minor optimizations for parsing integers.
1 parent 44a36be commit 3a5af1d

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

lexical-parse-integer/src/algorithm.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ macro_rules! algorithm {
742742
let mut value = T::ZERO;
743743
#[allow(unused_variables, unused_mut)]
744744
let mut has_suffix = false;
745-
if cannot_overflow && is_negative {
745+
if T::IS_SIGNED && cannot_overflow && is_negative {
746746
parse_digits_unchecked!(
747747
value,
748748
iter,
@@ -753,7 +753,7 @@ macro_rules! algorithm {
753753
has_suffix,
754754
true,
755755
);
756-
} if cannot_overflow {
756+
} else if cannot_overflow {
757757
parse_digits_unchecked!(
758758
value,
759759
iter,
@@ -764,7 +764,7 @@ macro_rules! algorithm {
764764
has_suffix,
765765
true,
766766
);
767-
} else if is_negative {
767+
} else if T::IS_SIGNED && is_negative {
768768
parse_digits_checked!(
769769
value,
770770
iter,

lexical-util/src/num.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -686,15 +686,21 @@ pub trait Integer:
686686
!self.is_odd()
687687
}
688688

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

0 commit comments

Comments
 (0)