From 00c155f45089798316173a14603028e0db7a7f9b Mon Sep 17 00:00:00 2001 From: Owen Leung Date: Wed, 27 Sep 2023 22:30:00 +0800 Subject: [PATCH] Implement custom fold for ZipSlice implement custom fold, and create benchmark test for measuring performance improvement --- benches/bench1.rs | 15 +++++++++++++++ benches/extra/zipslices.rs | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/benches/bench1.rs b/benches/bench1.rs index 084567177..56628d57d 100644 --- a/benches/bench1.rs +++ b/benches/bench1.rs @@ -169,6 +169,20 @@ fn zipdot_i32_zipslices(c: &mut Criterion) { }); } +fn zipdot_i32_zipslices_fold(c: &mut Criterion) { + let xs = vec![2; 1024]; + let ys = vec![2; 768]; + let xs = black_box(xs); + let ys = black_box(ys); + // output is 3072 + c.bench_function("zipdot i32 zipslices fold", move |b| { + b.iter(|| { + let sum = ZipSlices::new(&xs, &ys).fold(0i32, |acc, (&x, &y)| acc + (x * y)); + sum + }) + }); +} + fn zipdot_f32_zipslices(c: &mut Criterion) { let xs = vec![2f32; 1024]; let ys = vec![2f32; 768]; @@ -812,6 +826,7 @@ criterion_group!( zipslices, zipslices_mut, zipdot_i32_zipslices, + zipdot_i32_zipslices_fold, zipdot_f32_zipslices, zip_checked_counted_loop, zipdot_i32_checked_counted_loop, diff --git a/benches/extra/zipslices.rs b/benches/extra/zipslices.rs index 5476c0cb8..715e80793 100644 --- a/benches/extra/zipslices.rs +++ b/benches/extra/zipslices.rs @@ -92,6 +92,21 @@ where let len = self.len - self.index; (len, Some(len)) } + + #[inline(always)] + fn fold(mut self, acc: B, mut f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + let mut accum = acc; + for i in self.index..self.len { + unsafe { + accum = f(accum, (self.t.get_unchecked(i), self.u.get_unchecked(i))); + } + } + accum + } } impl DoubleEndedIterator for ZipSlices