-
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathreduce.rs
More file actions
112 lines (92 loc) · 2.65 KB
/
reduce.rs
File metadata and controls
112 lines (92 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;
const TEST_LARGE_OUTPUT: bool = false;
const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
true => 64,
false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
name: String,
numbers: [i64; LARGE_OUTPUT_LEN],
}
fn to_output(idx: &usize) -> Output {
let idx = *idx;
let prefix = match idx % 7 {
0 => "zero-",
3 => "three-",
_ => "sth-",
};
let fib = fibonacci(&(idx as u32));
let name = format!("{}-fib-{}", prefix, fib);
let mut numbers = [0i64; LARGE_OUTPUT_LEN];
for (i, x) in numbers.iter_mut().enumerate() {
*x = match (idx * 7 + i) % 3 {
0 => idx as i64 + i as i64,
_ => idx as i64 - i as i64,
};
}
Output { name, numbers }
}
fn reduce<'a>(a: &'a Output, b: &'a Output) -> &'a Output {
match a.name < b.name {
true => a,
false => b,
}
}
fn fibonacci(n: &u32) -> u32 {
let mut a = 0;
let mut b = 1;
for _ in 0..*n {
let c = a + b;
a = b;
b = c;
}
a
}
fn inputs(len: usize) -> Vec<Output> {
let mut rng = ChaCha8Rng::seed_from_u64(SEED);
(0..len)
.map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
.map(|x| to_output(&x))
.collect()
}
fn seq(inputs: &[Output]) -> Option<&Output> {
inputs.iter().reduce(reduce)
}
fn rayon(inputs: &[Output]) -> Option<&Output> {
use rayon::iter::ParallelIterator;
inputs.into_par_iter().reduce_with(reduce)
}
fn orx(inputs: &[Output]) -> Option<&Output> {
inputs.into_par().reduce(reduce)
}
fn run(c: &mut Criterion) {
let treatments = [65_536 * 2];
let mut group = c.benchmark_group("reduce");
for n in &treatments {
let input = inputs(*n);
let expected = seq(&input);
group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
assert_eq!(&expected, &seq(&input));
b.iter(|| seq(black_box(&input)))
});
group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
assert_eq!(&expected, &rayon(&input));
b.iter(|| rayon(black_box(&input)))
});
group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
assert_eq!(&expected, &orx(&input));
b.iter(|| orx(black_box(&input)))
});
}
group.finish();
}
criterion_group!(benches, run);
criterion_main!(benches);