Skip to content

Commit

Permalink
Efficient cloning of regions and flat stack (#45)
Browse files Browse the repository at this point in the history
Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru authored Jun 23, 2024
1 parent dbfd348 commit 4f4d747
Show file tree
Hide file tree
Showing 13 changed files with 399 additions and 59 deletions.
170 changes: 168 additions & 2 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,124 @@ fn vec_u_vn_s_prealloc(bencher: &mut Bencher) {
);
}

#[bench]
fn empty_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(bencher, vec![(); 1024]);
}
#[bench]
fn u64_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(bencher, vec![0u64; 1024]);
}
#[bench]
fn u32x2_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(bencher, vec![(0u32, 0u32); 1024]);
}
#[bench]
fn u8_u64_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(bencher, vec![(0u8, 0u64); 512]);
}
#[bench]
fn str10_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(bencher, vec!["grawwwwrr!"; 1024]);
}
#[bench]
fn str100_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(bencher, vec!["grawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrr!!!!!!!!!grawwwwrr!"; 1024]);
}
#[bench]
fn string10_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(bencher, vec![format!("grawwwwrr!"); 1024]);
}
#[bench]
fn string20_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(bencher, vec![format!("grawwwwrr!!!!!!!!!!!"); 512]);
}
#[bench]
fn vec_u_s_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(
bencher,
vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32],
);
}
#[bench]
fn vec_u_vn_s_copy_flat(bencher: &mut Bencher) {
_bench_copy_flat_containerized(
bencher,
vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32],
);
}

#[bench]
fn empty_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<OwnedRegion<_>, _>(bencher, vec![(); 1024]);
}
#[bench]
fn u64_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<OwnedRegion<_>, _>(bencher, vec![0u64; 1024]);
}
#[bench]
fn u32x2_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<OwnedRegion<_>, _>(bencher, vec![(0u32, 0u32); 1024]);
}
#[bench]
fn u8_u64_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<OwnedRegion<_>, _>(bencher, vec![(0u8, 0u64); 512]);
}
#[bench]
fn str10_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<OwnedRegion<_>, _>(bencher, vec!["grawwwwrr!"; 1024]);
}
#[bench]
fn str100_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<OwnedRegion<_>, _>(bencher, vec!["grawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrr!!!!!!!!!grawwwwrr!"; 1024]);
}
#[bench]
fn string10_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<SliceRegion<StringRegion>, _>(bencher, vec![format!("grawwwwrr!"); 1024]);
}
#[bench]
fn string20_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<SliceRegion<StringRegion>, _>(
bencher,
vec![format!("grawwwwrr!!!!!!!!!!!"); 512],
);
}
#[bench]
fn vec_u_s_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<SliceRegion<SliceRegion<TupleABRegion<MirrorRegion<_>, StringRegion>>>, _>(
bencher,
vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32],
);
}
#[bench]
fn vec_u_vn_s_copy_flat_region(bencher: &mut Bencher) {
_bench_copy_flat::<
SliceRegion<SliceRegion<TupleABCRegion<MirrorRegion<_>, OwnedRegion<_>, StringRegion>>>,
_,
>(
bencher,
vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32],
);
}
#[bench]
fn vec_u_vn_s_copy_flat_region_column(bencher: &mut Bencher) {
_bench_copy_flat::<
SliceRegion<
ColumnsRegion<
TupleABCRegion<
MirrorRegion<_>,
CollapseSequence<OwnedRegion<_>>,
CollapseSequence<StringRegion>,
>,
>,
>,
_,
>(
bencher,
vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32],
);
}

fn _bench_copy<T: Containerized + Eq>(bencher: &mut Bencher, record: T)
where
for<'a> <T as Containerized>::Region: Push<&'a T>,
Expand All @@ -281,6 +399,7 @@ where
siz += this_siz;
cap += this_cap
});
bencher.bytes = siz as u64;
println!("{siz} {cap}");
}

Expand All @@ -302,6 +421,7 @@ where
siz += this_siz;
cap += this_cap
});
bencher.bytes = siz as u64;
println!("{siz} {cap}");
}

Expand All @@ -321,25 +441,71 @@ fn _bench_realloc<T: Containerized + Eq>(bencher: &mut Bencher, record: T)
where
for<'a> <T as Containerized>::Region: Push<&'a T>,
{
let mut arena = FlatStack::default_impl::<T>();
bencher.iter(|| {
// prepare encoded data for bencher.bytes
let mut arena = FlatStack::default_impl::<T>();
arena = FlatStack::default_impl::<T>();
for _ in 0..1024 {
arena.copy(&record);
}
});
let (mut siz, mut cap) = (0, 0);
arena.heap_size(|this_siz, this_cap| {
siz += this_siz;
cap += this_cap
});
bencher.bytes = siz as u64;
}

fn _bench_prealloc<T: Containerized + Eq>(bencher: &mut Bencher, record: T)
where
for<'a> <T as Containerized>::Region: ReserveItems<&'a T> + Push<&'a T>,
{
let mut arena = FlatStack::default_impl::<T>();
bencher.iter(|| {
arena = FlatStack::default_impl::<T>();
// prepare encoded data for bencher.bytes
let mut arena = FlatStack::default_impl::<T>();
arena.reserve_items(std::iter::repeat(&record).take(1024));
for _ in 0..1024 {
arena.copy(&record);
}
});
let (mut siz, mut cap) = (0, 0);
arena.heap_size(|this_siz, this_cap| {
siz += this_siz;
cap += this_cap
});
bencher.bytes = siz as u64;
}

fn _bench_copy_flat_containerized<T>(bencher: &mut Bencher, record: T)
where
T: Containerized,
for<'a> <T as Containerized>::Region:
Push<&'a T> + Push<<<T as Containerized>::Region as Region>::ReadItem<'a>> + Clone,
{
_bench_copy_flat::<T::Region, T>(bencher, record)
}

fn _bench_copy_flat<R, T>(bencher: &mut Bencher, record: T)
where
for<'a> R: Region + Push<&'a T> + Push<<R as Region>::ReadItem<'a>> + Clone,
{
// prepare encoded data for bencher.bytes
let mut arena = FlatStack::<R>::default();
for _ in 0..1024 {
arena.copy(&record);
}
let mut target = FlatStack::<R>::default();

bencher.iter(|| {
target.clone_from(&arena);
});
let (mut siz, mut cap) = (0, 0);
arena.heap_size(|this_siz, this_cap| {
siz += this_siz;
cap += this_cap
});
bencher.bytes = siz as u64;
println!("{siz} {cap}");
}
18 changes: 16 additions & 2 deletions src/impls/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,25 @@ fn consolidate_slice<T: Ord>(slice: &mut [(T, usize)]) -> usize {
}

/// A region that encodes its data in a codec `C`.
#[derive(Default, Debug, Clone)]
pub struct CodecRegion<C: Codec, R = OwnedRegion<u8>> {
#[derive(Default, Debug)]
pub struct CodecRegion<C, R = OwnedRegion<u8>> {
inner: R,
codec: C,
}

impl<C: Clone, R: Clone> Clone for CodecRegion<C, R> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
codec: self.codec.clone(),
}
}
fn clone_from(&mut self, source: &Self) {
self.inner.clone_from(&source.inner);
self.codec.clone_from(&source.codec);
}
}

impl<C: Codec, R> Region for CodecRegion<C, R>
where
for<'a> R: Region<ReadItem<'a> = &'a [u8]> + 'a,
Expand Down Expand Up @@ -104,6 +117,7 @@ where
}

fn clear(&mut self) {
self.inner.clear();
self.codec = Default::default();
}

Expand Down
19 changes: 18 additions & 1 deletion src/impls/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use crate::{OwnedRegion, Push, Region};
/// assert!(row.iter().copied().eq(r.index(index).iter()));
/// }
/// ```
#[derive(Debug, Clone)]
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
Expand All @@ -67,6 +67,23 @@ where
inner: Vec<R>,
}

impl<R> Clone for ColumnsRegion<R>
where
R: Region + Clone,
{
fn clone(&self) -> Self {
Self {
indices: self.indices.clone(),
inner: self.inner.clone(),
}
}

fn clone_from(&mut self, source: &Self) {
self.indices.clone_from(&source.indices);
self.inner.clone_from(&source.inner);
}
}

impl<R> Region for ColumnsRegion<R>
where
R: Region,
Expand Down
46 changes: 37 additions & 9 deletions src/impls/deduplicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{Push, Region, ReserveItems};
///
/// assert_eq!(r.push("abc"), r.push("abc"));
/// ```
#[derive(Debug, Clone)]
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CollapseSequence<R: Region> {
/// Inner region.
Expand All @@ -27,6 +27,20 @@ pub struct CollapseSequence<R: Region> {
last_index: Option<R::Index>,
}

impl<R: Region + Clone> Clone for CollapseSequence<R> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
last_index: self.last_index,
}
}

fn clone_from(&mut self, source: &Self) {
self.inner.clone_from(&source.inner);
self.last_index = source.last_index;
}
}

impl<R: Region> Default for CollapseSequence<R> {
fn default() -> Self {
Self {
Expand Down Expand Up @@ -114,13 +128,9 @@ where
/// let index: usize = r.push(&b"abc");
/// assert_eq!(b"abc", r.index(index));
/// ```
#[derive(Debug, Clone)]
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ConsecutiveOffsetPairs<R, O = OffsetOptimized>
where
R: Region<Index = (usize, usize)>,
O: OffsetContainer<usize>,
{
pub struct ConsecutiveOffsetPairs<R, O = OffsetOptimized> {
/// Wrapped region
inner: R,
/// Storage for offsets. Always stores element 0.
Expand All @@ -129,8 +139,26 @@ where
last_index: usize,
}

impl<R: Region<Index = (usize, usize)>, O: OffsetContainer<usize>> Default
for ConsecutiveOffsetPairs<R, O>
impl<R: Clone, O: Clone> Clone for ConsecutiveOffsetPairs<R, O> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
offsets: self.offsets.clone(),
last_index: self.last_index,
}
}

fn clone_from(&mut self, source: &Self) {
self.inner.clone_from(&source.inner);
self.offsets.clone_from(&source.offsets);
self.last_index = source.last_index;
}
}

impl<R, O> Default for ConsecutiveOffsetPairs<R, O>
where
R: Default,
O: OffsetContainer<usize>,
{
#[inline]
fn default() -> Self {
Expand Down
Loading

0 comments on commit 4f4d747

Please sign in to comment.