Skip to content

Commit

Permalink
Auto merge of rust-lang#124294 - tspiteri:ilog-first-iter, r=the8472
Browse files Browse the repository at this point in the history
Unroll first iteration of checked_ilog loop

This follows the optimization of rust-lang#115913. As shown in rust-lang#115913 (comment), the performance was improved in all important cases, but some regressions were introduced for the benchmarks `u32_log_random_small`, `u8_log_random` and `u8_log_random_small`.

Basically, rust-lang#115913 changed the implementation from one division per iteration to one multiplication per iteration plus one division. When there are zero iterations, this is a regression from zero divisions to one division.

This PR avoids this by avoiding the division if we need zero iterations by returning `Some(0)` early. It also reduces the number of multiplications by one in all other cases.
  • Loading branch information
bors committed Jun 2, 2024
2 parents 7f0b19d + ad38f9b commit cd04000
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1148,9 +1148,12 @@ macro_rules! uint_impl {
pub const fn checked_ilog(self, base: Self) -> Option<u32> {
if self <= 0 || base <= 1 {
None
} else if self < base {
Some(0)
} else {
let mut n = 0;
let mut r = 1;
// Since base >= self, n >= 1
let mut n = 1;
let mut r = base;

// Optimization for 128 bit wide integers.
if Self::BITS == 128 {
Expand Down

0 comments on commit cd04000

Please sign in to comment.