summary refs log tree commit diff
path: root/src/libcore/benches
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2017-06-21 13:22:27 -0700
committerJosh Stone <jistone@redhat.com>2017-06-21 13:22:27 -0700
commit4a8ddac99e1edfb219e11c3ea2d6c43ccecb29ab (patch)
tree0b8806c71633a73dc6b369b61001ec9942cebceb /src/libcore/benches
parentb4038977a39f7c5bfa76cccf586930ec57befbad (diff)
downloadrust-4a8ddac99e1edfb219e11c3ea2d6c43ccecb29ab.tar.gz
rust-4a8ddac99e1edfb219e11c3ea2d6c43ccecb29ab.zip
Use `fold` to implement `Iterator::for_each`
The benefit of using internal iteration is shown in new benchmarks:

    test iter::bench_for_each_chain_fold     ... bench:     635,110 ns/iter (+/- 5,135)
    test iter::bench_for_each_chain_loop     ... bench:   2,249,983 ns/iter (+/- 42,001)
    test iter::bench_for_each_chain_ref_fold ... bench:   2,248,061 ns/iter (+/- 51,940)
Diffstat (limited to 'src/libcore/benches')
-rw-r--r--src/libcore/benches/iter.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs
index 93d38a5bc83..5b06229c21f 100644
--- a/src/libcore/benches/iter.rs
+++ b/src/libcore/benches/iter.rs
@@ -99,3 +99,50 @@ fn bench_zip_add(b: &mut Bencher) {
         add_zip(&source, &mut dst)
     });
 }
+
+/// `Iterator::for_each` implemented as a plain loop.
+fn for_each_loop<I, F>(iter: I, mut f: F) where
+    I: Iterator, F: FnMut(I::Item)
+{
+    for item in iter {
+        f(item);
+    }
+}
+
+/// `Iterator::for_each` implemented with `fold` for internal iteration.
+/// (except when `by_ref()` effectively disables that optimization.)
+fn for_each_fold<I, F>(iter: I, mut f: F) where
+    I: Iterator, F: FnMut(I::Item)
+{
+    iter.fold((), move |(), item| f(item));
+}
+
+#[bench]
+fn bench_for_each_chain_loop(b: &mut Bencher) {
+    b.iter(|| {
+        let mut acc = 0;
+        let iter = (0i64..1000000).chain(0..1000000).map(black_box);
+        for_each_loop(iter, |x| acc += x);
+        acc
+    });
+}
+
+#[bench]
+fn bench_for_each_chain_fold(b: &mut Bencher) {
+    b.iter(|| {
+        let mut acc = 0;
+        let iter = (0i64..1000000).chain(0..1000000).map(black_box);
+        for_each_fold(iter, |x| acc += x);
+        acc
+    });
+}
+
+#[bench]
+fn bench_for_each_chain_ref_fold(b: &mut Bencher) {
+    b.iter(|| {
+        let mut acc = 0;
+        let mut iter = (0i64..1000000).chain(0..1000000).map(black_box);
+        for_each_fold(iter.by_ref(), |x| acc += x);
+        acc
+    });
+}