diff --git a/src/uu/factor/Cargo.toml b/src/uu/factor/Cargo.toml index c4e7e8469..cb77c5d19 100644 --- a/src/uu/factor/Cargo.toml +++ b/src/uu/factor/Cargo.toml @@ -23,6 +23,7 @@ uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [dev-dependencies] +array-init = "2.0.0" criterion = "0.3" paste = "0.1.18" quickcheck = "0.9.2" @@ -32,6 +33,10 @@ rand_chacha = "0.2.2" name = "gcd" harness = false +[[bench]] +name = "table" +harness = false + [[bin]] name = "factor" path = "src/main.rs" diff --git a/src/uu/factor/benches/table.rs b/src/uu/factor/benches/table.rs new file mode 100644 index 000000000..8fae7cef6 --- /dev/null +++ b/src/uu/factor/benches/table.rs @@ -0,0 +1,44 @@ +use array_init::array_init; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use uu_factor::{table::*, Factors}; + +fn table(c: &mut Criterion) { + let inputs = { + // Deterministic RNG; use an explicitely-named RNG to guarantee stability + use rand::{RngCore, SeedableRng}; + use rand_chacha::ChaCha8Rng; + 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())) + }; + + let mut group = c.benchmark_group("table"); + for a in inputs.take(10) { + let a_str = format!("{:?}", a); + group.bench_with_input( + BenchmarkId::from_parameter("chunked_".to_owned() + &a_str), + &a, + |b, &a| { + b.iter(|| factor_chunk(&mut a.clone(), &mut array_init(|_| Factors::one()))); + }, + ); + group.bench_with_input( + BenchmarkId::from_parameter("seq_".to_owned() + &a_str), + &a, + |b, &a| { + b.iter(|| { + let mut n_s = a.clone(); + let mut f_s: [_; CHUNK_SIZE] = array_init(|_| Factors::one()); + for (n, f) in n_s.iter_mut().zip(f_s.iter_mut()) { + factor(n, f) + } + }) + }, + ); + } + group.finish() +} + +criterion_group!(benches, table); +criterion_main!(benches); diff --git a/src/uu/factor/src/cli.rs b/src/uu/factor/src/cli.rs index fb7b3f192..ee4c8a4c4 100644 --- a/src/uu/factor/src/cli.rs +++ b/src/uu/factor/src/cli.rs @@ -13,13 +13,13 @@ use std::error::Error; use std::io::{self, stdin, stdout, BufRead, Write}; mod factor; -pub(crate) use factor::*; +pub use factor::*; use uucore::InvalidEncodingHandling; mod miller_rabin; pub mod numeric; mod rho; -mod table; +pub mod table; static SYNTAX: &str = "[OPTION] [NUMBER]..."; static SUMMARY: &str = "Print the prime factors of the given number(s). diff --git a/src/uu/factor/src/table.rs b/src/uu/factor/src/table.rs index cbd4af5e4..72628054c 100644 --- a/src/uu/factor/src/table.rs +++ b/src/uu/factor/src/table.rs @@ -12,7 +12,7 @@ use crate::Factors; include!(concat!(env!("OUT_DIR"), "/prime_table.rs")); -pub(crate) fn factor(num: &mut u64, factors: &mut Factors) { +pub fn factor(num: &mut u64, factors: &mut Factors) { for &(prime, inv, ceil) in P_INVS_U64 { if *num == 1 { break; @@ -42,3 +42,10 @@ pub(crate) fn factor(num: &mut u64, factors: &mut Factors) { } } } + +pub const CHUNK_SIZE: usize = 4; +pub fn factor_chunk(n_s: &mut [u64; CHUNK_SIZE], f_s: &mut [Factors; CHUNK_SIZE]) { + for (n, s) in n_s.iter_mut().zip(f_s.iter_mut()) { + factor(n, s); + } +}