Skip to content

Commit

Permalink
Add micro-benchmarks for map_indexed and map_keyed (#115)
Browse files Browse the repository at this point in the history
* Add micro-benchmarks for map_keyed and map_indexed

* Add some optimizations
  • Loading branch information
lukechu10 authored Jun 9, 2021
1 parent 8c9b1f3 commit 6c1f192
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 14 deletions.
27 changes: 25 additions & 2 deletions packages/sycamore/benches/reactivity.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use sycamore::prelude::*;
use sycamore::rx::{map_indexed, map_keyed};

pub fn bench(c: &mut Criterion) {
c.bench_function("reactivity_signals", |b| {
Expand All @@ -10,7 +11,7 @@ pub fn bench(c: &mut Criterion) {
let value = state.get();
state.set(*value + 1);
}
})
});
});

c.bench_function("reactivity_effects", |b| {
Expand All @@ -23,7 +24,29 @@ pub fn bench(c: &mut Criterion) {
for _i in 0..1000 {
state.set(*state.get() + 1);
}
})
});
});

c.bench_function("reactivity map indexed", |b| {
b.iter(|| {
let v = Signal::new((0..100).collect());
let mut mapped = map_indexed(v.handle(), |x| *x * 2);
mapped();

v.set((100..200).collect());
mapped();
});
});

c.bench_function("reactivity map keyed", |b| {
b.iter(|| {
let v = Signal::new((0..100).collect());
let mut mapped = map_keyed(v.handle(), |x| *x * 2);
mapped();

v.set((100..200).collect());
mapped();
});
});
}

Expand Down
4 changes: 2 additions & 2 deletions packages/sycamore/src/flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ where
let template = Rc::clone(&template);
move |x| template(x.clone())
});
Template::new_lazy(move || Template::new_fragment((*mapped()).clone()))
Template::new_lazy(move || Template::new_fragment(mapped()))
}

/// Props for [`Indexed`].
Expand Down Expand Up @@ -114,5 +114,5 @@ where
let template = Rc::clone(&template);
move |x| template(x.clone())
});
Template::new_lazy(move || Template::new_fragment((*mapped()).clone()))
Template::new_lazy(move || Template::new_fragment(mapped()))
}
27 changes: 17 additions & 10 deletions packages/sycamore/src/rx/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ use super::*;
pub fn map_keyed<T, U>(
list: StateHandle<Vec<T>>,
map_fn: impl Fn(&T) -> U + 'static,
) -> impl FnMut() -> Rc<Vec<U>>
) -> impl FnMut() -> Vec<U>
where
T: Eq + Clone + Hash,
U: Clone + 'static,
{
// Previous state used for diffing.
let mut items = Vec::new();
let mapped = Rc::new(RefCell::new(Vec::<U>::new()));
let mut items = Rc::new(Vec::new());
let mapped = Rc::new(RefCell::new(Vec::new()));
let mut scopes: Vec<Option<Rc<ReactiveScope>>> = Vec::new();

move || {
Expand Down Expand Up @@ -140,26 +140,26 @@ where
scopes.truncate(new_items.len());

// 4) save a copy of the mapped items for the next update.
items = (*new_items).clone();
items = Rc::clone(&new_items);
debug_assert!([items.len(), mapped.borrow().len(), scopes.len()]
.iter()
.all(|l| *l == new_items.len()));

Rc::new((*mapped).clone().into_inner())
mapped.borrow().clone()
})
}
}

pub fn map_indexed<T, U>(
list: StateHandle<Vec<T>>,
map_fn: impl Fn(&T) -> U + 'static,
) -> impl FnMut() -> Rc<Vec<U>>
) -> impl FnMut() -> Vec<U>
where
T: PartialEq + Clone,
U: Clone + 'static,
{
// Previous state used for diffing.
let mut items = Vec::new();
let mut items = Rc::new(Vec::new());
let mapped = Rc::new(RefCell::new(Vec::new()));
let mut scopes = Vec::new();

Expand All @@ -169,9 +169,16 @@ where
if new_items.is_empty() {
// Fast path for removing all items.
drop(mem::take(&mut scopes));
items = Vec::new();
items = Rc::new(Vec::new());
*mapped.borrow_mut() = Vec::new();
} else {
// Pre-allocate space needed
if new_items.len() > items.len() {
let new_count = new_items.len() - items.len();
mapped.borrow_mut().reserve(new_count);
scopes.reserve(new_count);
}

for (i, new_item) in new_items.iter().enumerate() {
let item = items.get(i);

Expand Down Expand Up @@ -203,13 +210,13 @@ where
scopes.truncate(new_items.len());

// save a copy of the mapped items for the next update.
items = (*new_items).clone();
items = Rc::clone(&new_items);
debug_assert!([items.len(), mapped.borrow().len(), scopes.len()]
.iter()
.all(|l| *l == new_items.len()));
}

Rc::new((*mapped).clone().into_inner())
mapped.borrow().clone()
})
}
}
Expand Down

0 comments on commit 6c1f192

Please sign in to comment.