forked from rust-ndarray/ndarray
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnumeric.rs
77 lines (70 loc) · 2.01 KB
/
numeric.rs
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
#![feature(test)]
extern crate test;
use test::Bencher;
extern crate ndarray;
use ndarray::prelude::*;
use ndarray::{Zip, FoldWhile};
const N: usize = 1024;
const X: usize = 64;
const Y: usize = 16;
#[bench]
fn clip(bench: &mut Bencher)
{
let mut a = Array::linspace(0., 127., N * 2).into_shape([X, Y * 2]).unwrap();
let min = 2.;
let max = 5.;
bench.iter(|| {
a.mapv_inplace(|mut x| {
if x < min { x = min }
if x > max { x = max }
x
})
});
}
#[bench]
fn max_early_return(bench: &mut Bencher)
{
fn max(arr: &Array2<f64>) -> Option<&f64>
{
if let Some(mut max) = arr.first() {
if let Some(slc) = arr.as_slice_memory_order() {
for item in slc.iter().skip(1) {
match max.partial_cmp(item) {
None => return None,
Some(::std::cmp::Ordering::Less) => max = item,
_ => {},
}
}
Some(max)
} else {
Zip::from(arr).fold_while(Some(max), |acc, x|
match acc.partial_cmp(&Some(x)) {
None => FoldWhile::Done(None),
Some(::std::cmp::Ordering::Less) => FoldWhile::Continue(Some(x)),
_ => FoldWhile::Continue(acc),
}).into_inner()
}
} else {
None
}
}
let mut a = Array::linspace(0., 127., N * 2).into_shape([X, Y * 2]).unwrap();
bench.iter(|| max(&a));
}
#[bench]
fn max_short(bench: &mut Bencher) {
fn max(arr: &Array2<f64>) -> Option<&f64> {
if let Some(first) = arr.first() {
let max = arr.fold(first, |acc, x| if x>acc {x} else {acc});
if max == max {
Some(max)
} else {
None
}
} else {
None
}
}
let mut a = Array::linspace(0., 127., N * 2).into_shape([X, Y * 2]).unwrap();
bench.iter(|| max(&a));
}