From 4247abe6014593bdda0a4a8035c60cffeb19d993 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 5 Mar 2021 09:46:19 -0800 Subject: [PATCH] implement xorshift* for benchmarking --- Cargo.toml | 3 --- benches/bigint.rs | 7 ++----- benches/gcd.rs | 7 ++----- benches/rng/mod.rs | 38 ++++++++++++++++++++++++++++++++++++++ benches/roots.rs | 9 +++------ ci/big_rand/src/torture.rs | 2 +- 6 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 benches/rng/mod.rs diff --git a/Cargo.toml b/Cargo.toml index c6aadb7a..6e54ee32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,6 +72,3 @@ default-features = false [build-dependencies] autocfg = "1" - -[dev-dependencies] -rand_xorshift = "0.3" diff --git a/benches/bigint.rs b/benches/bigint.rs index 8163aa64..b7f5fd21 100644 --- a/benches/bigint.rs +++ b/benches/bigint.rs @@ -5,14 +5,11 @@ extern crate test; use num_bigint::{BigInt, BigUint, RandBigInt}; use num_traits::{FromPrimitive, Num, One, Zero}; -use rand::prelude::*; -use rand_xorshift::XorShiftRng; use std::mem::replace; use test::Bencher; -fn get_rng() -> impl Rng { - XorShiftRng::seed_from_u64(0x1234_5678_9abc_def0) -} +mod rng; +use rng::get_rng; fn multiply_bench(b: &mut Bencher, xbits: u64, ybits: u64) { let mut rng = get_rng(); diff --git a/benches/gcd.rs b/benches/gcd.rs index 61028a7d..c211b6ef 100644 --- a/benches/gcd.rs +++ b/benches/gcd.rs @@ -6,13 +6,10 @@ extern crate test; use num_bigint::{BigUint, RandBigInt}; use num_integer::Integer; use num_traits::Zero; -use rand::prelude::*; -use rand_xorshift::XorShiftRng; use test::Bencher; -fn get_rng() -> impl Rng { - XorShiftRng::seed_from_u64(0x1234_5678_9abc_def0) -} +mod rng; +use rng::get_rng; fn bench(b: &mut Bencher, bits: u64, gcd: fn(&BigUint, &BigUint) -> BigUint) { let mut rng = get_rng(); diff --git a/benches/rng/mod.rs b/benches/rng/mod.rs new file mode 100644 index 00000000..33e4f0fa --- /dev/null +++ b/benches/rng/mod.rs @@ -0,0 +1,38 @@ +use rand::RngCore; + +pub(crate) fn get_rng() -> impl RngCore { + XorShiftStar { + a: 0x0123_4567_89AB_CDEF, + } +} + +/// Simple `Rng` for benchmarking without additional dependencies +struct XorShiftStar { + a: u64, +} + +impl RngCore for XorShiftStar { + fn next_u32(&mut self) -> u32 { + self.next_u64() as u32 + } + + fn next_u64(&mut self) -> u64 { + // https://en.wikipedia.org/wiki/Xorshift#xorshift* + self.a ^= self.a >> 12; + self.a ^= self.a << 25; + self.a ^= self.a >> 27; + self.a.wrapping_mul(0x2545_F491_4F6C_DD1D) + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + for chunk in dest.chunks_mut(8) { + let bytes = self.next_u64().to_le_bytes(); + let slice = &bytes[..chunk.len()]; + chunk.copy_from_slice(slice) + } + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { + Ok(self.fill_bytes(dest)) + } +} diff --git a/benches/roots.rs b/benches/roots.rs index 0f365ada..7afc4f76 100644 --- a/benches/roots.rs +++ b/benches/roots.rs @@ -4,10 +4,11 @@ extern crate test; use num_bigint::{BigUint, RandBigInt}; -use rand::prelude::*; -use rand_xorshift::XorShiftRng; use test::Bencher; +mod rng; +use rng::get_rng; + // The `big64` cases demonstrate the speed of cases where the value // can be converted to a `u64` primitive for faster calculation. // @@ -16,10 +17,6 @@ use test::Bencher; // // The `big2k` and `big4k` cases are too big for `f64`, and use a simpler guess. -fn get_rng() -> impl Rng { - XorShiftRng::seed_from_u64(0x1234_5678_9abc_def0) -} - fn check(x: &BigUint, n: u32) { let root = x.nth_root(n); if n == 2 { diff --git a/ci/big_rand/src/torture.rs b/ci/big_rand/src/torture.rs index 58400883..72059ef2 100644 --- a/ci/big_rand/src/torture.rs +++ b/ci/big_rand/src/torture.rs @@ -3,7 +3,7 @@ use num_traits::Zero; use rand::prelude::*; use rand_xorshift::XorShiftRng; -fn get_rng() -> impl Rng { +fn get_rng() -> XorShiftRng { XorShiftRng::seed_from_u64(0x1234_5678_9abc_def0) }