1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-01 13:37:48 +00:00

factor::table: Fixup microbenchmark

Previous version would perform an amount of work proportional to `CHUNK_SIZE`,
so this wasn't a valid way to benchmark at multiple values of that constant.

The `TryInto` implementation for `&mut [T]` to `&mut [T; N]` relies on `const`
generics, and is available in (stable) Rust v1.51 and later.
This commit is contained in:
nicoo 2021-04-29 15:45:04 +02:00
parent 1fd5f9da25
commit 7c287542c7
2 changed files with 18 additions and 4 deletions

View file

@ -1,8 +1,16 @@
use std::convert::TryInto;
use array_init::array_init;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use uu_factor::{table::*, Factors};
fn table(c: &mut Criterion) {
const INPUT_SIZE: usize = 128;
assert!(
INPUT_SIZE % CHUNK_SIZE == 0,
"INPUT_SIZE ({}) is not divisible by CHUNK_SIZE ({})",
INPUT_SIZE,
CHUNK_SIZE
);
let inputs = {
// Deterministic RNG; use an explicitely-named RNG to guarantee stability
use rand::{RngCore, SeedableRng};
@ -10,7 +18,7 @@ fn table(c: &mut Criterion) {
const SEED: u64 = 0xdead_bebe_ea75_cafe;
let mut rng = ChaCha8Rng::seed_from_u64(SEED);
std::iter::repeat_with(move || array_init(|_| rng.next_u64()))
std::iter::repeat_with(move || array_init::<_, _, INPUT_SIZE>(|_| rng.next_u64()))
};
let mut group = c.benchmark_group("table");
@ -20,7 +28,13 @@ fn table(c: &mut Criterion) {
BenchmarkId::from_parameter("chunked_".to_owned() + &a_str),
&a,
|b, &a| {
b.iter(|| factor_chunk(&mut a.clone(), &mut array_init(|_| Factors::one())));
b.iter(|| {
let mut n_s = a.clone();
let mut f_s: [_; INPUT_SIZE] = array_init(|_| Factors::one());
for (n_s, f_s) in n_s.chunks_mut(CHUNK_SIZE).zip(f_s.chunks_mut(CHUNK_SIZE)) {
factor_chunk(n_s.try_into().unwrap(), f_s.try_into().unwrap())
}
})
},
);
group.bench_with_input(
@ -29,7 +43,7 @@ fn table(c: &mut Criterion) {
|b, &a| {
b.iter(|| {
let mut n_s = a.clone();
let mut f_s: [_; CHUNK_SIZE] = array_init(|_| Factors::one());
let mut f_s: [_; INPUT_SIZE] = array_init(|_| Factors::one());
for (n, f) in n_s.iter_mut().zip(f_s.iter_mut()) {
factor(n, f)
}

View file

@ -43,7 +43,7 @@ pub fn factor(num: &mut u64, factors: &mut Factors) {
}
}
pub const CHUNK_SIZE: usize = 4;
pub const CHUNK_SIZE: usize = 8;
pub fn factor_chunk(n_s: &mut [u64; CHUNK_SIZE], f_s: &mut [Factors; CHUNK_SIZE]) {
for &(prime, inv, ceil) in P_INVS_U64 {
if n_s[0] == 1 && n_s[1] == 1 && n_s[2] == 1 && n_s[3] == 1 {