From 1fd2f1687c6483fd3386f838c30332215c3f32b2 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Mon, 25 Feb 2019 16:44:04 +0100 Subject: [PATCH 1/4] Have all methods of Filter and FilterMap use internal iteration --- src/libcore/iter/adapters/mod.rs | 37 ++++++-------------------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index bca1b76dbb975..d4ad22c16bbfa 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -681,12 +681,7 @@ impl Iterator for Filter where P: FnMut(&I::Item) -> bool #[inline] fn next(&mut self) -> Option { - for x in &mut self.iter { - if (self.predicate)(&x) { - return Some(x); - } - } - None + self.try_for_each(Err).err() } #[inline] @@ -707,12 +702,9 @@ impl Iterator for Filter where P: FnMut(&I::Item) -> bool // Using the branchless version will also simplify the LLVM byte code, thus // leaving more budget for LLVM optimizations. #[inline] - fn count(mut self) -> usize { - let mut count = 0; - for x in &mut self.iter { - count += (self.predicate)(&x) as usize; - } - count + fn count(self) -> usize { + let mut predicate = self.predicate; + self.iter.map(|x| predicate(&x) as usize).sum() } #[inline] @@ -746,12 +738,7 @@ impl DoubleEndedIterator for Filter { #[inline] fn next_back(&mut self) -> Option { - for x in self.iter.by_ref().rev() { - if (self.predicate)(&x) { - return Some(x); - } - } - None + self.try_rfold((), |_, x| Err(x)).err() } #[inline] @@ -820,12 +807,7 @@ impl Iterator for FilterMap #[inline] fn next(&mut self) -> Option { - for x in self.iter.by_ref() { - if let Some(y) = (self.f)(x) { - return Some(y); - } - } - None + self.try_for_each(Err).err() } #[inline] @@ -863,12 +845,7 @@ impl DoubleEndedIterator for FilterMap { #[inline] fn next_back(&mut self) -> Option { - for x in self.iter.by_ref().rev() { - if let Some(y) = (self.f)(x) { - return Some(y); - } - } - None + self.try_rfold((), |_, x| Err(x)).err() } #[inline] From 88847718f0cca57124cbd1bce12fc938c5bde088 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Wed, 27 Feb 2019 11:44:30 +0100 Subject: [PATCH 2/4] Add relevant benchmarks --- src/libcore/benches/iter.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs index fe852e42b5cd3..5cc2bce846d87 100644 --- a/src/libcore/benches/iter.rs +++ b/src/libcore/benches/iter.rs @@ -306,3 +306,31 @@ fn bench_skip_then_zip(b: &mut Bencher) { assert_eq!(s, 2009900); }); } + +#[bench] +fn bench_filter_count(b: &mut Bencher) { + b.iter(|| { + (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count() + }) +} + +#[bench] +fn bench_filter_ref_count(b: &mut Bencher) { + b.iter(|| { + (0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count() + }) +} + +#[bench] +fn bench_filter_chain_count(b: &mut Bencher) { + b.iter(|| { + (0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count() + }) +} + +#[bench] +fn bench_filter_chain_ref_count(b: &mut Bencher) { + b.iter(|| { + (0i64..1000000).chain(0..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count() + }) +} \ No newline at end of file From ec2e4ba919a65a972019925b5b33d0f309f467fc Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Wed, 27 Feb 2019 11:46:37 +0100 Subject: [PATCH 3/4] Improve existing benchmarks to prevent extreme optimizations --- src/libcore/benches/iter.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs index 5cc2bce846d87..4f3d6f379022b 100644 --- a/src/libcore/benches/iter.rs +++ b/src/libcore/benches/iter.rs @@ -185,13 +185,13 @@ bench_sums! { bench_sums! { bench_filter_sum, bench_filter_ref_sum, - (0i64..1000000).filter(|x| x % 2 == 0) + (0i64..1000000).filter(|x| x % 3 == 0) } bench_sums! { bench_filter_chain_sum, bench_filter_chain_ref_sum, - (0i64..1000000).chain(0..1000000).filter(|x| x % 2 == 0) + (0i64..1000000).chain(0..1000000).filter(|x| x % 3 == 0) } bench_sums! { From 88bd624a88692dd4bbda5f3f324f0035dc041534 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Wed, 27 Feb 2019 13:22:18 +0100 Subject: [PATCH 4/4] Add trailing newline --- src/libcore/benches/iter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs index 4f3d6f379022b..1dd2bd3ee78aa 100644 --- a/src/libcore/benches/iter.rs +++ b/src/libcore/benches/iter.rs @@ -333,4 +333,4 @@ fn bench_filter_chain_ref_count(b: &mut Bencher) { b.iter(|| { (0i64..1000000).chain(0..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count() }) -} \ No newline at end of file +}