about summary refs log tree commit diff
path: root/src/libcoretest
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2015-04-08 14:25:22 +1000
committerHuon Wilson <dbau.pp+github@gmail.com>2015-04-10 14:42:17 +1000
commitc2258d6d042353bfa6daad6008bcd3c0af3f13de (patch)
treefcba6d8badc0d442aea89d98f8b3470b26df2b60 /src/libcoretest
parentd9146bf8ba0bdf98a46c4656899e54802e96ac0c (diff)
downloadrust-c2258d6d042353bfa6daad6008bcd3c0af3f13de.tar.gz
rust-c2258d6d042353bfa6daad6008bcd3c0af3f13de.zip
Optimise Iterator::{max, max_by, min, min_by}.
The main change in this patch is removing the use of `Option` inside the
inner loops of those functions to avoid comparisons where one branch
will only trigger on the first pass through the loop.

The included benchmarks go from:

    test bench_max    ... bench:       372 ns/iter (+/- 118)
    test bench_max_by ... bench:       428 ns/iter (+/- 33)
    test bench_max_by2 ... bench:      7128 ns/iter (+/- 326)

to:

    test bench_max    ... bench:       317 ns/iter (+/- 64)
    test bench_max_by ... bench:       356 ns/iter (+/- 270)
    test bench_max_by2 ... bench:      1387 ns/iter (+/- 183)

Problem noticed in http://www.reddit.com/r/rust/comments/31syce/using_iterators_to_find_the_index_of_the_min_or/
Diffstat (limited to 'src/libcoretest')
-rw-r--r--src/libcoretest/iter.rs31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
index af80d347f02..ef050d46e1f 100644
--- a/src/libcoretest/iter.rs
+++ b/src/libcoretest/iter.rs
@@ -901,3 +901,34 @@ fn bench_multiple_take(b: &mut Bencher) {
         }
     });
 }
+
+fn scatter(x: i32) -> i32 { (x * 31) % 127 }
+
+#[bench]
+fn bench_max_by(b: &mut Bencher) {
+    b.iter(|| {
+        let it = 0..100;
+        it.max_by(|&x| scatter(x))
+    })
+}
+
+// http://www.reddit.com/r/rust/comments/31syce/using_iterators_to_find_the_index_of_the_min_or/
+#[bench]
+fn bench_max_by2(b: &mut Bencher) {
+    fn max_index_iter(array: &[i32]) -> usize {
+        array.iter().enumerate().max_by(|&(_, item)| item).unwrap().0
+    }
+
+    let mut data = vec![0i32; 1638];
+    data[514] = 9999;
+
+    b.iter(|| max_index_iter(&data));
+}
+
+#[bench]
+fn bench_max(b: &mut Bencher) {
+    b.iter(|| {
+        let it = 0..100;
+        it.map(scatter).max()
+    })
+}