Add benchmark suite

Signed-off-by: Benjamin Schultzer <benjamin@schultzer.com>
This commit is contained in:
Benjamin Schultzer 2019-06-18 17:56:58 -07:00
parent a5be1028a7
commit 2cd88e96b1
5 changed files with 138 additions and 1 deletions

View file

@ -30,6 +30,8 @@ members = [
[dev-dependencies]
no-panic = "0.1.8"
rand = "0.6.5"
paste = "0.1.5"
[build-dependencies]
rand = { version = "0.6.5", optional = true }

View file

@ -37,6 +37,12 @@ fn foo(x: f32) {
The API documentation can be found [here](https://docs.rs/libm).
## Benchmark
[benchmark]: #benchmark
Run `cargo +nightly bench`
NOTE: remember to have nightly installed `rustup install nightly`
## Contributing
Please check [CONTRIBUTING.md](CONTRIBUTING.md)

View file

@ -71,3 +71,14 @@ jobs:
- template: ci/azure-install-rust.yml
- bash: cargo build -p cb
displayName: "Check compiler-builtins still probably builds"
- job: benchmarks
pool:
vmImage: ubuntu-16.04
steps:
- template: ci/azure-install-rust.yml
- bash: cargo bench
displayName: "Benchmarks"
variables:
TOOLCHAIN: nightly

View file

@ -0,0 +1,118 @@
#![feature(test)]
extern crate paste;
extern crate rand;
extern crate test;
use rand::Rng;
use test::Bencher;
macro_rules! unary {
($($func:ident),*) => ($(
paste::item! {
#[bench]
pub fn [<$func>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let x = rng.gen::<f64>();
bh.iter(|| test::black_box(libm::[<$func>](x)))
}
#[bench]
pub fn [<$func f>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let x = rng.gen::<f32>();
bh.iter(|| test::black_box(libm::[<$func f>](x)))
}
}
)*);
}
macro_rules! binary {
($($func:ident),*) => ($(
paste::item! {
#[bench]
pub fn [<$func>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let x = rng.gen::<f64>();
let y = rng.gen::<f64>();
bh.iter(|| test::black_box(libm::[<$func>](x, y)))
}
#[bench]
pub fn [<$func f>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let x = rng.gen::<f32>();
let y = rng.gen::<f32>();
bh.iter(|| test::black_box(libm::[<$func f>](x, y)))
}
}
)*);
($($func:ident);*) => ($(
paste::item! {
#[bench]
pub fn [<$func>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let x = rng.gen::<f64>();
let n = rng.gen::<i32>();
bh.iter(|| test::black_box(libm::[<$func>](x, n)))
}
#[bench]
pub fn [<$func f>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let x = rng.gen::<f32>();
let n = rng.gen::<i32>();
bh.iter(|| test::black_box(libm::[<$func f>](x, n)))
}
}
)*);
}
macro_rules! trinary {
($($func:ident),*) => ($(
paste::item! {
#[bench]
pub fn [<$func>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let x = rng.gen::<f64>();
let y = rng.gen::<f64>();
let z = rng.gen::<f64>();
bh.iter(|| test::black_box(libm::[<$func>](x, y, z)))
}
#[bench]
pub fn [<$func f>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let x = rng.gen::<f32>();
let y = rng.gen::<f32>();
let z = rng.gen::<f32>();
bh.iter(|| test::black_box(libm::[<$func f>](x, y, z)))
}
}
)*);
}
macro_rules! bessel {
($($func:ident),*) => ($(
paste::item! {
#[bench]
pub fn [<$func>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let mut n = rng.gen::<i32>();
n &= 0xffff;
let x = rng.gen::<f64>();
bh.iter(|| test::black_box(libm::[<$func>](n, x)))
}
#[bench]
pub fn [<$func f>](bh: &mut Bencher) {
let mut rng = rand::thread_rng();
let mut n = rng.gen::<i32>();
n &= 0xffff;
let x = rng.gen::<f32>();
bh.iter(|| test::black_box(libm::[<$func f>](n, x)))
}
}
)*);
}
unary!(
acos, acosh, asin, atan, cbrt, ceil, cos, cosh, erf, exp, exp2, exp10, expm1, fabs, floor, j0,
j1, lgamma, log, log1p, log2, log10, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc, y0, y1
);
binary!(atan2, copysign, fdim, fmax, fmin, fmod, hypot, pow);
trinary!(fma);
bessel!(jn, yn);
binary!(ldexp; scalbn);

View file

@ -479,7 +479,7 @@ mod tests {
.for_each(|s| s.iter().for_each(|val| pow_test(base, *val, expected)));
}
fn test_sets(sets: &[&[f64]], computed: &Fn(f64) -> f64, expected: &Fn(f64) -> f64) {
fn test_sets(sets: &[&[f64]], computed: &dyn Fn(f64) -> f64, expected: &dyn Fn(f64) -> f64) {
sets.iter().for_each(|s| {
s.iter().for_each(|val| {
let exp = expected(*val);