diff options
| author | Giles Cope <gilescope@gmail.com> | 2021-05-18 08:51:20 +0100 |
|---|---|---|
| committer | gilescope <gilescope@gmail.com> | 2022-03-26 14:25:29 +0000 |
| commit | 13d85ea8809910a685c52acf32f4d37632905eda (patch) | |
| tree | f68ba5d2d4a8b63b9225f9bc34ff4de9bc911047 | |
| parent | 0a11090053d73af94de3c1a96d125c4980a16626 (diff) | |
| download | rust-13d85ea8809910a685c52acf32f4d37632905eda.tar.gz rust-13d85ea8809910a685c52acf32f4d37632905eda.zip | |
add likely and clearer comments
| -rw-r--r-- | library/core/src/num/mod.rs | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 5fd697fd428..19419334839 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1068,8 +1068,13 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par let mut result = T::from_u32(0); - if radix <= 16 && digits.len() <= mem::size_of::<T>() * 2 - is_signed_ty as usize { - // SAFETY: Consider the highest radix of 16: + if intrinsics::likely( + radix <= 16 && digits.len() <= mem::size_of::<T>() * 2 - is_signed_ty as usize, + ) { + // SAFETY: We can take this fast path when `radix.pow(digits.len()) - 1 <= T::MAX` + // but the condition above is a faster (conservative) approximation of this. + // + // Consider the highest radix of 16: // `u8::MAX` is `ff` (2 characters), `u16::MAX` is `ffff` (4 characters) // We can be sure that any src len of 2 would fit in a u8 so we don't need // to check for overflow. @@ -1088,9 +1093,14 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par let overflow_err = || PIE { kind: if is_positive { PosOverflow } else { NegOverflow } }; for &c in digits { + // When `radix` is passed in as a literal, rather than doing a slow `imul` + // then the compiler can use a shift if `radix` is a power of 2. + // (*10 can also be turned into *8 + *2). + // When the compiler can't use these optimisations, + // there is a latency of several cycles so doing the + // multiply before we need to use the result helps. let mul = result.checked_mul(radix); let x = (c as char).to_digit(radix).ok_or(PIE { kind: InvalidDigit })?; - // multiply done early for performance reasons. result = mul.ok_or_else(overflow_err)?; result = additive_op(&result, x).ok_or_else(overflow_err)?; } |
