From 435cafe5ba0aeaaad7c217161ad2c4abd8edb39b Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Fri, 8 Nov 2024 21:10:06 +0100 Subject: [PATCH] bench Signed-off-by: Moritz Hoffmann --- benches/bench.rs | 145 +++++++++++++++++++-------------------- src/impls.rs | 1 - src/impls/slice.rs | 4 +- src/impls/slice_owned.rs | 12 ++-- src/impls/vec.rs | 22 ++++-- src/lib.rs | 13 ++++ 6 files changed, 105 insertions(+), 92 deletions(-) diff --git a/benches/bench.rs b/benches/bench.rs index d951bff..87d785d 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -1,13 +1,8 @@ //! A simple benchmark for flatcontainer, adopted from `columnation`'s benchmark. -/* + use codspeed_bencher_compat::{benchmark_group, benchmark_main, Bencher}; -use flatcontainer::impls::deduplicate::{CollapseSequence, ConsecutiveIndexPairs}; -use flatcontainer::impls::index::IndexOptimized; use flatcontainer::impls::tuple::{TupleABCRegion, TupleABRegion}; -use flatcontainer::{ - ColumnsRegion, FlatStack, MirrorRegion, OwnedRegion, Push, Region, RegionPreference, - ReserveItems, SliceRegion, StringRegion, -}; +use flatcontainer::{Clear, HeapSize, Index, OwnedRegion, Push, Region, RegionPreference, ReserveItems, SliceRegion, StringRegion}; fn empty_copy(bencher: &mut Bencher) { _bench_copy(bencher, vec![(); 1024]); @@ -64,12 +59,12 @@ fn str100_copy_region(bencher: &mut Bencher) { fn string10_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>(bencher, vec![format!("grawwwwrr!"); 1024]); } -fn string10_copy_region_collapse(bencher: &mut Bencher) { - _bench_copy_region::< - SliceRegion>, IndexOptimized>, - _, - >(bencher, vec![format!("grawwwwrr!"); 1024]); -} +// fn string10_copy_region_collapse(bencher: &mut Bencher) { +// _bench_copy_region::< +// SliceRegion>, IndexOptimized>, +// _, +// >(bencher, vec![format!("grawwwwrr!"); 1024]); +// } fn string20_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>( bencher, @@ -77,37 +72,37 @@ fn string20_copy_region(bencher: &mut Bencher) { ); } fn vec_u_s_copy_region(bencher: &mut Bencher) { - _bench_copy_region::, StringRegion>>>, _>( + _bench_copy_region::, StringRegion>>>, _>( bencher, vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32], ); } fn vec_u_vn_s_copy_region(bencher: &mut Bencher) { _bench_copy_region::< - SliceRegion, OwnedRegion<_>, StringRegion>>>, - _, - >( - bencher, - vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32], - ); -} -fn vec_u_vn_s_copy_region_column(bencher: &mut Bencher) { - _bench_copy_region::< - SliceRegion< - ColumnsRegion< - TupleABCRegion< - MirrorRegion<_>, - CollapseSequence>, - CollapseSequence, - >, - >, - >, + SliceRegion, OwnedRegion<()>, StringRegion>>>, _, >( bencher, vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32], ); } +// fn vec_u_vn_s_copy_region_column(bencher: &mut Bencher) { +// _bench_copy_region::< +// SliceRegion< +// ColumnsRegion< +// TupleABCRegion< +// MirrorRegion<_>, +// CollapseSequence>, +// CollapseSequence, +// >, +// >, +// >, +// _, +// >( +// bencher, +// vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32], +// ); +// } fn empty_clone(bencher: &mut Bencher) { _bench_clone(bencher, vec![(); 1024]); @@ -276,37 +271,37 @@ fn string20_copy_flat_region(bencher: &mut Bencher) { ); } fn vec_u_s_copy_flat_region(bencher: &mut Bencher) { - _bench_copy_flat::, StringRegion>>>, _>( + _bench_copy_flat::, StringRegion>>>, _>( bencher, vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32], ); } fn vec_u_vn_s_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::< - SliceRegion, OwnedRegion<_>, StringRegion>>>, - _, - >( - bencher, - vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32], - ); -} -fn vec_u_vn_s_copy_flat_region_column(bencher: &mut Bencher) { - _bench_copy_flat::< - SliceRegion< - ColumnsRegion< - TupleABCRegion< - MirrorRegion<_>, - CollapseSequence>, - CollapseSequence, - >, - >, - >, + SliceRegion, OwnedRegion<()>, StringRegion>>>, _, >( bencher, vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32], ); } +// fn vec_u_vn_s_copy_flat_region_column(bencher: &mut Bencher) { +// _bench_copy_flat::< +// SliceRegion< +// ColumnsRegion< +// TupleABCRegion< +// MirrorRegion<_>, +// CollapseSequence>, +// CollapseSequence, +// >, +// >, +// >, +// _, +// >( +// bencher, +// vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32], +// ); +// } fn set_bytes(target: &mut u64, bytes: usize) { if std::env::var("BYTES").is_ok() { @@ -316,15 +311,15 @@ fn set_bytes(target: &mut u64, bytes: usize) { fn _bench_copy(bencher: &mut Bencher, record: T) where - for<'a> ::Region: Push<&'a T>, + for<'a> ::Region: Default + HeapSize + Clear+ Push<&'a T>, { // prepare encoded data for bencher.bytes - let mut arena = FlatStack::default_impl::(); + let mut arena = T::Region::default(); bencher.iter(|| { arena.clear(); for _ in 0..1024 { - arena.copy(&record); + arena.push(&record); } }); let (mut siz, mut cap) = (0, 0); @@ -335,17 +330,17 @@ where set_bytes(&mut bencher.bytes, siz); } -fn _bench_copy_region(bencher: &mut Bencher, record: T) +fn _bench_copy_region(bencher: &mut Bencher, record: T) where - for<'a> R: Push<&'a T>, + for<'a> R: Default + HeapSize + Clear + Push<&'a T>, { // prepare encoded data for bencher.bytes - let mut arena = FlatStack::::default(); + let mut arena = R::default(); bencher.iter(|| { arena.clear(); for _ in 0..1024 { - arena.copy(&record); + arena.push(&record); } }); let (mut siz, mut cap) = (0, 0); @@ -370,14 +365,14 @@ fn _bench_clone(bencher: &mut Bencher, record: fn _bench_realloc(bencher: &mut Bencher, record: T) where - for<'a> ::Region: Push<&'a T>, + for<'a> ::Region: Default + HeapSize + Push<&'a T>, { - let mut arena = FlatStack::default_impl::(); + let mut arena = T::Region::default(); bencher.iter(|| { // prepare encoded data for bencher.bytes - arena = FlatStack::default_impl::(); + arena = T::Region::default(); for _ in 0..1024 { - arena.copy(&record); + arena.push(&record); } }); let (mut siz, mut cap) = (0, 0); @@ -389,15 +384,15 @@ where fn _bench_prealloc(bencher: &mut Bencher, record: T) where - for<'a> ::Region: ReserveItems<&'a T> + Push<&'a T>, + for<'a> ::Region: Default + HeapSize + ReserveItems<&'a T> + Push<&'a T>, { - let mut arena = FlatStack::default_impl::(); + let mut arena = T::Region::default(); bencher.iter(|| { - arena = FlatStack::default_impl::(); + arena = T::Region::default(); // prepare encoded data for bencher.bytes arena.reserve_items(std::iter::repeat(&record).take(1024)); for _ in 0..1024 { - arena.copy(&record); + arena.push(&record); } }); let (mut siz, mut cap) = (0, 0); @@ -412,21 +407,22 @@ fn _bench_copy_flat_preference(bencher: &mut Bencher, record: T) where T: RegionPreference, for<'a> ::Region: - Push<&'a T> + Push<<::Region as Region>::ReadItem<'a>> + Clone, + Default +Index+ HeapSize + + Push<&'a T> + Push<<::Region as Index>::ReadItem<'a>> + Clone, { _bench_copy_flat::(bencher, record) } fn _bench_copy_flat(bencher: &mut Bencher, record: T) where - for<'a> R: Region + Push<&'a T> + Push<::ReadItem<'a>> + Clone, + for<'a> R: Default + Index + HeapSize + Push<&'a T> + Push<::ReadItem<'a>> + Clone, { // prepare encoded data for bencher.bytes - let mut arena = FlatStack::::default(); + let mut arena = R::default(); for _ in 0..1024 { - arena.copy(&record); + arena.push(&record); } - let mut target = FlatStack::::default(); + let mut target = R::default(); bencher.iter(|| { target.clone_from(&arena); @@ -486,7 +482,7 @@ benchmark_group!( str10_copy_region, string10_copy_flat_region, string10_copy_region, - string10_copy_region_collapse, + // string10_copy_region_collapse, string20_copy_flat_region, string20_copy_region, u32x2_copy_flat_region, @@ -498,9 +494,9 @@ benchmark_group!( vec_u_s_copy_flat_region, vec_u_s_copy_region, vec_u_vn_s_copy_flat_region, - vec_u_vn_s_copy_flat_region_column, + // vec_u_vn_s_copy_flat_region_column, vec_u_vn_s_copy_region, - vec_u_vn_s_copy_region_column, + // vec_u_vn_s_copy_region_column, ); benchmark_group!( alloc, @@ -524,4 +520,3 @@ benchmark_group!( vec_u_vn_s_realloc, ); benchmark_main!(clone, copy, copy_flat, copy_region, alloc); -*/ diff --git a/src/impls.rs b/src/impls.rs index d0a2c61..0f4c5fc 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -5,7 +5,6 @@ // pub mod deduplicate; // pub mod huffman_container; // pub mod index; -// pub mod mirror; pub mod option; pub mod result; pub mod slice; diff --git a/src/impls/slice.rs b/src/impls/slice.rs index 1cb49f1..65884b6 100644 --- a/src/impls/slice.rs +++ b/src/impls/slice.rs @@ -437,9 +437,7 @@ where { #[inline] fn push(&mut self, items: &'a [T]) { - for item in items.iter() { - self.inner.push(item); - } + self.inner.push_extend(items); self.bounds .push(self.inner.len().try_into().expect("must fit")); } diff --git a/src/impls/slice_owned.rs b/src/impls/slice_owned.rs index 3e34f60..4ce109d 100644 --- a/src/impls/slice_owned.rs +++ b/src/impls/slice_owned.rs @@ -6,7 +6,7 @@ use std::marker::PhantomData; use serde::{Deserialize, Serialize}; // use crate::impls::storage::{PushStorage, Storage}; -use crate::{Clear, HeapSize, Index, IndexAs, Len, Push, PushIter, Region, Reserve, ReserveItems}; +use crate::{Clear, HeapSize, Index, IndexAs, Len, Push, PushIter, PushSlice, Region, Reserve, ReserveItems}; type Idx = u64; @@ -174,9 +174,7 @@ where { #[inline] fn push(&mut self, items: [T; N]) { - for item in items { - self.slices.push(item); - } + self.slices.push_extend(items); self.bounds .push(self.slices.len().try_into().expect("must fit")); } @@ -220,14 +218,12 @@ where impl Push<&[T]> for OwnedRegion where T: Clone, - S: for<'a> Push<&'a T> + Len, + S: PushSlice + Len, B: Push, { #[inline] fn push(&mut self, items: &[T]) { - for item in items { - self.slices.push(item); - } + self.slices.push_slice(items); self.bounds .push(self.slices.len().try_into().expect("must fit")); } diff --git a/src/impls/vec.rs b/src/impls/vec.rs index 3aa1f25..0b602e1 100644 --- a/src/impls/vec.rs +++ b/src/impls/vec.rs @@ -1,6 +1,6 @@ //! Definitions to use `Vec` as a region. -use crate::{Clear, HeapSize, Index, IndexAs, Len, Push, Region, Reserve, ReserveItems}; +use crate::{Clear, HeapSize, Index, IndexAs, Len, Push, PushSlice, Region, Reserve, ReserveItems}; impl Region for Vec { #[inline(always)] @@ -49,18 +49,30 @@ impl Push for Vec { fn push(&mut self, item: T) { self.push(item); } + + #[inline(always)] + fn push_extend>(&mut self, iter: I) { + Extend::extend(self, iter); + } +} + +impl PushSlice for Vec { + #[inline(always)] + fn push_slice(&mut self, slice: &[T]) { + self.extend_from_slice(slice); + } } -impl Push<&T> for Vec { +impl<'a, T: Clone> Push<&'a T> for Vec { #[inline(always)] - fn push(&mut self, item: &T) { + fn push(&mut self, item: &'a T) { self.push(item.clone()); } } -impl Push<&&T> for Vec { +impl<'a, 'b, T: Clone> Push<&'a &'b T> for Vec { #[inline(always)] - fn push(&mut self, item: &&T) { + fn push(&mut self, item: &'a &'b T) { self.push((*item).clone()); } } diff --git a/src/lib.rs b/src/lib.rs index 008b721..ebb8dfe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,6 +63,19 @@ impl RegionPreference for &T { pub trait Push { /// Push `item` into self. fn push(&mut self, item: T); + + /// Pushes many items into self. + fn push_extend>(&mut self, iter: I) { + for item in iter { + self.push(item); + } + } +} + +/// TODO +pub trait PushSlice { + /// TODO + fn push_slice(&mut self, slice: &[T]); } /// Reserve space in the receiving region.