Skip to content

Commit 6029085

Browse files
committed
Auto merge of rust-lang#119430 - NCGThompson:int-pow-bench, r=cuviper
Add Benchmarks for int_pow Methods. There is quite a bit of room for improvement in performance of the `int_pow` family of methods. I added benchmarks for those functions. In particular, there are benchmarks for small compile-time bases to measure the effect of rust-lang#114390. ~~I added a lot (245), but all but 22 of them are marked with `#[ignore]`. There are a lot of macros, and I would appreciate feedback on how to simplify them.~~ ~~To run benches relevant to rust-lang#114390, use `./x bench core --stage 1 -- pow_base_const --include-ignored`.~~
2 parents 62d7ed4 + c65c35b commit 6029085

File tree

4 files changed

+100
-12
lines changed

4 files changed

+100
-12
lines changed
+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use rand::Rng;
2+
use test::{black_box, Bencher};
3+
4+
const ITERATIONS: usize = 128; // Uses an ITERATIONS * 20 Byte stack allocation
5+
type IntType = i128; // Hardest native type to multiply
6+
const EXPONENT_MAX: u32 = 31;
7+
const MAX_BASE: IntType = 17; // +-17 ** 31 <= IntType::MAX
8+
9+
macro_rules! pow_bench_template {
10+
($name:ident, $inner_macro:ident, $base_macro:ident) => {
11+
#[bench]
12+
fn $name(bench: &mut Bencher) {
13+
// Frequent black_box calls can add latency and prevent optimizations, so for
14+
// variable parameters we premake an array and pass the
15+
// reference through black_box outside of the loop.
16+
let mut rng = crate::bench_rng();
17+
let base_array: [IntType; ITERATIONS] =
18+
core::array::from_fn(|_| rng.gen_range((-MAX_BASE..=MAX_BASE)));
19+
let exp_array: [u32; ITERATIONS] =
20+
core::array::from_fn(|_| rng.gen_range((0..=EXPONENT_MAX)));
21+
22+
bench.iter(|| {
23+
#[allow(unused, unused_mut)]
24+
let mut base_iter = black_box(&base_array).into_iter();
25+
let mut exp_iter = black_box(&exp_array).into_iter();
26+
27+
(0..ITERATIONS).fold((0 as IntType, false), |acc, _| {
28+
// Sometimes constants don't propogate all the way to the
29+
// inside of the loop, so we call a custom expression every cycle
30+
// rather than iter::repeat(CONST)
31+
let base: IntType = $base_macro!(base_iter);
32+
let exp: u32 = *exp_iter.next().unwrap();
33+
34+
let r: (IntType, bool) = $inner_macro!(base, exp);
35+
(acc.0 ^ r.0, acc.1 ^ r.1)
36+
})
37+
});
38+
}
39+
};
40+
}
41+
42+
// This may panic if it overflows.
43+
macro_rules! inner_pow {
44+
($base:ident, $exp:ident) => {
45+
($base.pow($exp), false)
46+
};
47+
}
48+
49+
macro_rules! inner_wrapping {
50+
($base:ident, $exp:ident) => {
51+
($base.wrapping_pow($exp), false)
52+
};
53+
}
54+
55+
macro_rules! inner_overflowing {
56+
($base:ident, $exp:ident) => {
57+
$base.overflowing_pow($exp)
58+
};
59+
}
60+
61+
// This will panic if it overflows.
62+
macro_rules! inner_checked_unwrapped {
63+
($base:ident, $exp:ident) => {
64+
($base.checked_pow($exp).unwrap(), false)
65+
};
66+
}
67+
68+
macro_rules! inner_saturating {
69+
($base:ident, $exp:ident) => {
70+
($base.saturating_pow($exp), false)
71+
};
72+
}
73+
74+
macro_rules! make_const_base {
75+
($name:ident, $x:literal) => {
76+
macro_rules! $name {
77+
($iter:ident) => {
78+
$x
79+
};
80+
}
81+
};
82+
}
83+
84+
make_const_base!(const_base_m7, -7);
85+
make_const_base!(const_base_m8, -8);
86+
87+
macro_rules! variable_base {
88+
($iter:ident) => {
89+
*$iter.next().unwrap()
90+
};
91+
}
92+
93+
pow_bench_template!(pow_variable, inner_pow, variable_base);
94+
pow_bench_template!(wrapping_pow_variable, inner_wrapping, variable_base);
95+
pow_bench_template!(overflowing_pow_variable, inner_overflowing, variable_base);
96+
pow_bench_template!(checked_pow_variable, inner_checked_unwrapped, variable_base);
97+
pow_bench_template!(saturating_pow_variable, inner_saturating, variable_base);
98+
pow_bench_template!(pow_m7, inner_pow, const_base_m7);
99+
pow_bench_template!(pow_m8, inner_pow, const_base_m8);

library/core/benches/num/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod dec2flt;
22
mod flt2dec;
33
mod int_log;
4+
mod int_pow;
45

56
use std::str::FromStr;
67
use test::{black_box, Bencher};

library/std/src/num.rs

-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
#[cfg(test)]
1010
mod tests;
1111

12-
#[cfg(test)]
13-
mod benches;
14-
1512
#[stable(feature = "saturating_int_impl", since = "1.74.0")]
1613
pub use core::num::Saturating;
1714
#[stable(feature = "rust1", since = "1.0.0")]

library/std/src/num/benches.rs

-9
This file was deleted.

0 commit comments

Comments
 (0)