Skip to content

Commit ce7fd64

Browse files
authored
Merge pull request rust-random#1439 from dhardy/upgrade-criterion
Upgrade criterion
2 parents 02955d1 + d47d2cf commit ce7fd64

File tree

11 files changed

+272
-0
lines changed

11 files changed

+272
-0
lines changed

Cargo.toml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
[package]
2+
name = "benches"
3+
version = "0.1.0"
4+
edition = "2021"
5+
publish = false
6+
7+
[dependencies]
8+
9+
[dev-dependencies]
10+
rand = { path = "..", features = ["small_rng", "nightly"] }
11+
rand_pcg = { path = "../rand_pcg" }
12+
rand_chacha = { path = "../rand_chacha" }
13+
rand_distr = { path = "../rand_distr" }
14+
criterion = "0.5"
15+
criterion-cycles-per-byte = "0.6"
16+
17+
[[bench]]
18+
name = "distributions"
19+
path = "src/distributions.rs"
20+
harness = false
21+
22+
[[bench]]
23+
name = "uniform"
24+
path = "src/uniform.rs"
25+
harness = false
26+
27+
[[bench]]
28+
name = "seq_choose"
29+
path = "src/seq_choose.rs"
30+
harness = false
31+
32+
[[bench]]
33+
name = "shuffle"
34+
path = "src/shuffle.rs"
35+
harness = false
36+
37+
[[bench]]
38+
name = "uniform_float"
39+
path = "src/uniform_float.rs"
40+
harness = false
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/distributions.rs

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
// Copyright 2018-2021 Developers of the Rand project.
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
#![feature(custom_inner_attributes)]
10+
11+
// Rustfmt splits macro invocations to shorten lines; in this case longer-lines are more readable
12+
#![rustfmt::skip]
13+
14+
const RAND_BENCH_N: u64 = 1000;
15+
16+
use criterion::{criterion_group, criterion_main, Criterion,
17+
Throughput};
18+
use criterion_cycles_per_byte::CyclesPerByte;
19+
20+
use core::mem::size_of;
21+
22+
use rand::prelude::*;
23+
use rand_distr::*;
24+
25+
// At this time, distributions are optimised for 64-bit platforms.
26+
use rand_pcg::Pcg64Mcg;
27+
28+
macro_rules! distr_int {
29+
($group:ident, $fnn:expr, $ty:ty, $distr:expr) => {
30+
$group.throughput(Throughput::Bytes(
31+
size_of::<$ty>() as u64 * RAND_BENCH_N));
32+
$group.bench_function($fnn, |c| {
33+
let mut rng = Pcg64Mcg::from_entropy();
34+
let distr = $distr;
35+
36+
c.iter(|| {
37+
let mut accum: $ty = 0;
38+
for _ in 0..RAND_BENCH_N {
39+
let x: $ty = distr.sample(&mut rng);
40+
accum = accum.wrapping_add(x);
41+
}
42+
accum
43+
});
44+
});
45+
};
46+
}
47+
48+
macro_rules! distr_float {
49+
($group:ident, $fnn:expr, $ty:ty, $distr:expr) => {
50+
$group.throughput(Throughput::Bytes(
51+
size_of::<$ty>() as u64 * RAND_BENCH_N));
52+
$group.bench_function($fnn, |c| {
53+
let mut rng = Pcg64Mcg::from_entropy();
54+
let distr = $distr;
55+
56+
c.iter(|| {
57+
let mut accum = 0.;
58+
for _ in 0..RAND_BENCH_N {
59+
let x: $ty = distr.sample(&mut rng);
60+
accum += x;
61+
}
62+
accum
63+
});
64+
});
65+
};
66+
}
67+
68+
macro_rules! distr {
69+
($group:ident, $fnn:expr, $ty:ty, $distr:expr) => {
70+
$group.throughput(Throughput::Bytes(
71+
size_of::<$ty>() as u64 * RAND_BENCH_N));
72+
$group.bench_function($fnn, |c| {
73+
let mut rng = Pcg64Mcg::from_entropy();
74+
let distr = $distr;
75+
76+
c.iter(|| {
77+
let mut accum: u32 = 0;
78+
for _ in 0..RAND_BENCH_N {
79+
let x: $ty = distr.sample(&mut rng);
80+
accum = accum.wrapping_add(x as u32);
81+
}
82+
accum
83+
});
84+
});
85+
};
86+
}
87+
88+
macro_rules! distr_arr {
89+
($group:ident, $fnn:expr, $ty:ty, $distr:expr) => {
90+
$group.throughput(Throughput::Bytes(
91+
size_of::<$ty>() as u64 * RAND_BENCH_N));
92+
$group.bench_function($fnn, |c| {
93+
let mut rng = Pcg64Mcg::from_entropy();
94+
let distr = $distr;
95+
96+
c.iter(|| {
97+
let mut accum: u32 = 0;
98+
for _ in 0..RAND_BENCH_N {
99+
let x: $ty = distr.sample(&mut rng);
100+
accum = accum.wrapping_add(x[0] as u32);
101+
}
102+
accum
103+
});
104+
});
105+
};
106+
}
107+
108+
macro_rules! sample_binomial {
109+
($group:ident, $name:expr, $n:expr, $p:expr) => {
110+
distr_int!($group, $name, u64, Binomial::new($n, $p).unwrap())
111+
};
112+
}
113+
114+
fn bench(c: &mut Criterion<CyclesPerByte>) {
115+
{
116+
let mut g = c.benchmark_group("exp");
117+
distr_float!(g, "exp", f64, Exp::new(1.23 * 4.56).unwrap());
118+
distr_float!(g, "exp1_specialized", f64, Exp1);
119+
distr_float!(g, "exp1_general", f64, Exp::new(1.).unwrap());
120+
}
121+
122+
{
123+
let mut g = c.benchmark_group("normal");
124+
distr_float!(g, "normal", f64, Normal::new(-1.23, 4.56).unwrap());
125+
distr_float!(g, "standardnormal_specialized", f64, StandardNormal);
126+
distr_float!(g, "standardnormal_general", f64, Normal::new(0., 1.).unwrap());
127+
distr_float!(g, "log_normal", f64, LogNormal::new(-1.23, 4.56).unwrap());
128+
g.throughput(Throughput::Bytes(size_of::<f64>() as u64 * RAND_BENCH_N));
129+
g.bench_function("iter", |c| {
130+
let mut rng = Pcg64Mcg::from_entropy();
131+
let distr = Normal::new(-2.71828, 3.14159).unwrap();
132+
let mut iter = distr.sample_iter(&mut rng);
133+
134+
c.iter(|| {
135+
let mut accum = 0.0;
136+
for _ in 0..RAND_BENCH_N {
137+
accum += iter.next().unwrap();
138+
}
139+
accum
140+
});
141+
});
142+
}
143+
144+
{
145+
let mut g = c.benchmark_group("skew_normal");
146+
distr_float!(g, "shape_zero", f64, SkewNormal::new(0.0, 1.0, 0.0).unwrap());
147+
distr_float!(g, "shape_positive", f64, SkewNormal::new(0.0, 1.0, 100.0).unwrap());
148+
distr_float!(g, "shape_negative", f64, SkewNormal::new(0.0, 1.0, -100.0).unwrap());
149+
}
150+
151+
{
152+
let mut g = c.benchmark_group("gamma");
153+
distr_float!(g, "gamma_large_shape", f64, Gamma::new(10., 1.0).unwrap());
154+
distr_float!(g, "gamma_small_shape", f64, Gamma::new(0.1, 1.0).unwrap());
155+
distr_float!(g, "beta_small_param", f64, Beta::new(0.1, 0.1).unwrap());
156+
distr_float!(g, "beta_large_param_similar", f64, Beta::new(101., 95.).unwrap());
157+
distr_float!(g, "beta_large_param_different", f64, Beta::new(10., 1000.).unwrap());
158+
distr_float!(g, "beta_mixed_param", f64, Beta::new(0.5, 100.).unwrap());
159+
}
160+
161+
{
162+
let mut g = c.benchmark_group("cauchy");
163+
distr_float!(g, "cauchy", f64, Cauchy::new(4.2, 6.9).unwrap());
164+
}
165+
166+
{
167+
let mut g = c.benchmark_group("triangular");
168+
distr_float!(g, "triangular", f64, Triangular::new(0., 1., 0.9).unwrap());
169+
}
170+
171+
{
172+
let mut g = c.benchmark_group("geometric");
173+
distr_int!(g, "geometric", u64, Geometric::new(0.5).unwrap());
174+
distr_int!(g, "standard_geometric", u64, StandardGeometric);
175+
}
176+
177+
{
178+
let mut g = c.benchmark_group("weighted");
179+
distr_int!(g, "weighted_i8", usize, WeightedIndex::new(&[1i8, 2, 3, 4, 12, 0, 2, 1]).unwrap());
180+
distr_int!(g, "weighted_u32", usize, WeightedIndex::new(&[1u32, 2, 3, 4, 12, 0, 2, 1]).unwrap());
181+
distr_int!(g, "weighted_f64", usize, WeightedIndex::new(&[1.0f64, 0.001, 1.0/3.0, 4.01, 0.0, 3.3, 22.0, 0.001]).unwrap());
182+
distr_int!(g, "weighted_large_set", usize, WeightedIndex::new((0..10000).rev().chain(1..10001)).unwrap());
183+
distr_int!(g, "weighted_alias_method_i8", usize, WeightedAliasIndex::new(vec![1i8, 2, 3, 4, 12, 0, 2, 1]).unwrap());
184+
distr_int!(g, "weighted_alias_method_u32", usize, WeightedAliasIndex::new(vec![1u32, 2, 3, 4, 12, 0, 2, 1]).unwrap());
185+
distr_int!(g, "weighted_alias_method_f64", usize, WeightedAliasIndex::new(vec![1.0f64, 0.001, 1.0/3.0, 4.01, 0.0, 3.3, 22.0, 0.001]).unwrap());
186+
distr_int!(g, "weighted_alias_method_large_set", usize, WeightedAliasIndex::new((0..10000).rev().chain(1..10001).collect()).unwrap());
187+
}
188+
189+
{
190+
let mut g = c.benchmark_group("binomial");
191+
sample_binomial!(g, "binomial", 20, 0.7);
192+
sample_binomial!(g, "binomial_small", 1_000_000, 1e-30);
193+
sample_binomial!(g, "binomial_1", 1, 0.9);
194+
sample_binomial!(g, "binomial_10", 10, 0.9);
195+
sample_binomial!(g, "binomial_100", 100, 0.99);
196+
sample_binomial!(g, "binomial_1000", 1000, 0.01);
197+
sample_binomial!(g, "binomial_1e12", 1000_000_000_000, 0.2);
198+
}
199+
200+
{
201+
let mut g = c.benchmark_group("poisson");
202+
distr_float!(g, "poisson", f64, Poisson::new(4.0).unwrap());
203+
}
204+
205+
{
206+
let mut g = c.benchmark_group("zipf");
207+
distr_float!(g, "zipf", f64, Zipf::new(10, 1.5).unwrap());
208+
distr_float!(g, "zeta", f64, Zeta::new(1.5).unwrap());
209+
}
210+
211+
{
212+
let mut g = c.benchmark_group("bernoulli");
213+
distr!(g, "bernoulli", bool, Bernoulli::new(0.18).unwrap());
214+
}
215+
216+
{
217+
let mut g = c.benchmark_group("circle");
218+
distr_arr!(g, "circle", [f64; 2], UnitCircle);
219+
}
220+
221+
{
222+
let mut g = c.benchmark_group("sphere");
223+
distr_arr!(g, "sphere", [f64; 3], UnitSphere);
224+
}
225+
}
226+
227+
criterion_group!(
228+
name = benches;
229+
config = Criterion::default().with_measurement(CyclesPerByte);
230+
targets = bench
231+
);
232+
criterion_main!(benches);
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)