about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGiles Cope <gilescope@gmail.com>2021-05-18 08:51:20 +0100
committergilescope <gilescope@gmail.com>2022-03-26 14:25:29 +0000
commit13d85ea8809910a685c52acf32f4d37632905eda (patch)
treef68ba5d2d4a8b63b9225f9bc34ff4de9bc911047
parent0a11090053d73af94de3c1a96d125c4980a16626 (diff)
downloadrust-13d85ea8809910a685c52acf32f4d37632905eda.tar.gz
rust-13d85ea8809910a685c52acf32f4d37632905eda.zip
add likely and clearer comments
-rw-r--r--library/core/src/num/mod.rs16
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)?;
         }