use num_integer::Integer; use num_traits::checked_pow; use num_traits::{AsPrimitive, PrimInt, WrappingAdd, WrappingMul}; use test::{black_box, Bencher};
impl<T> BenchInteger for T where T: Integer + PrimInt + WrappingAdd + WrappingMul + 'static {}
fn bench<T, F>(b: &mut Bencher, v: &[T], f: F, n: u32) where
T: BenchInteger,
F: Fn(&T) -> T,
{ // Pre-validate the results... for i in v { let rt = f(i); if *i >= T::zero() { let rt1 = rt + T::one();
assert!(rt.pow(n) <= *i); iflet Some(x) = checked_pow(rt1, n as usize) {
assert!(*i < x);
}
} else { let rt1 = rt - T::one();
assert!(rt < T::zero());
assert!(*i <= rt.pow(n)); iflet Some(x) = checked_pow(rt1, n as usize) {
assert!(x < *i);
}
};
}
// Now just run as fast as we can!
b.iter(|| { for i in v {
black_box(f(i));
}
});
}
// Simple PRNG so we don't have to worry about rand compatibility fn lcg<T>(x: T) -> T where
u32: AsPrimitive<T>,
T: BenchInteger,
{ // LCG parameters from Numerical Recipes // (but we're applying it to arbitrary sizes) const LCG_A: u32 = 1664525; const LCG_C: u32 = 1013904223;
x.wrapping_mul(&LCG_A.as_()).wrapping_add(&LCG_C.as_())
}
fn bench_rand<T, F>(b: &mut Bencher, f: F, n: u32) where
u32: AsPrimitive<T>,
T: BenchInteger,
F: Fn(&T) -> T,
{ letmut x: T = 3u32.as_(); let v: Vec<T> = (0..1000)
.map(|_| {
x = lcg(x);
x
})
.collect();
bench(b, &v, f, n);
}
fn bench_rand_pos<T, F>(b: &mut Bencher, f: F, n: u32) where
u32: AsPrimitive<T>,
T: BenchInteger,
F: Fn(&T) -> T,
{ letmut x: T = 3u32.as_(); let v: Vec<T> = (0..1000)
.map(|_| {
x = lcg(x); while x < T::zero() {
x = lcg(x);
}
x
})
.collect();
bench(b, &v, f, n);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.