pub struct Memo<T>(/* private fields */);Expand description
A shared lazy cache of a pure computation over tracked signals and memos.
Reads validate dependencies synchronously, including inside a batch. Equal results keep the previous cached value and suppress downstream effects that have no other changed dependencies. Keep a handle alive while using the memo; dropping the last handle releases its cache, captures, and subscriptions. Computation and equality functions must be pure. Managed signal writes and effect creation during evaluation panic before changing reactive state.
Implementations§
Source§impl<T: 'static> Memo<T>
impl<T: 'static> Memo<T>
Sourcepub fn with<R>(&self, read: impl FnOnce(&T) -> R) -> R
pub fn with<R>(&self, read: impl FnOnce(&T) -> R) -> R
Borrow the current cached value and subscribe the consuming effect/memo. Do not change dependencies while this callback borrows the cache.
Sourcepub fn with_untracked<R>(&self, read: impl FnOnce(&T) -> R) -> R
pub fn with_untracked<R>(&self, read: impl FnOnce(&T) -> R) -> R
Read without subscribing the caller. The memo still tracks its own inputs.
Source§impl<T: Clone + 'static> Memo<T>
impl<T: Clone + 'static> Memo<T>
Sourcepub fn get(&self) -> T
pub fn get(&self) -> T
Examples found in repository?
examples/memo_workload.rs (line 23)
6fn run(name: &str, cached: bool, consumers: usize, updates: u64, work: u64, group: u64) {
7 let input = signal(0_u64);
8 let computations = Rc::new(Cell::new(0_u64));
9 let renders = Rc::new(Cell::new(0_u64));
10 let compute = {
11 let (input, computations) = (input.clone(), computations.clone());
12 move || {
13 computations.set(computations.get() + 1);
14 let mut n = input.get() / group;
15 for _ in 0..work {
16 n = black_box(n.wrapping_mul(6364136223846793005).wrapping_add(1));
17 }
18 n
19 }
20 };
21 let read: Rc<dyn Fn() -> u64> = if cached {
22 let value = memo(compute);
23 Rc::new(move || value.get())
24 } else {
25 let value = derived(compute);
26 Rc::new(move || value.get())
27 };
28 let subscriptions: Vec<_> = (0..consumers)
29 .map(|_| {
30 let (read, renders) = (read.clone(), renders.clone());
31 effect(move || {
32 black_box(read());
33 renders.set(renders.get() + 1);
34 })
35 })
36 .collect();
37 computations.set(0);
38 renders.set(0);
39 let start = Instant::now();
40 for value in 1..=updates {
41 input.set(black_box(value));
42 }
43 let elapsed = start.elapsed().as_micros();
44 let mode = if cached { "Memo" } else { "Derived" };
45 println!(
46 "{name},{mode},{consumers},{updates},{},{},{elapsed}",
47 computations.get(),
48 renders.get()
49 );
50 assert_eq!(
51 computations.get(),
52 updates * if cached { 1 } else { consumers as u64 }
53 );
54 assert_eq!(
55 renders.get(),
56 if cached { updates / group } else { updates } * consumers as u64
57 );
58 drop(subscriptions);
59}pub fn get_untracked(&self) -> T
Trait Implementations§
Auto Trait Implementations§
impl<T> !RefUnwindSafe for Memo<T>
impl<T> !Send for Memo<T>
impl<T> !Sync for Memo<T>
impl<T> !UnwindSafe for Memo<T>
impl<T> Freeze for Memo<T>
impl<T> Unpin for Memo<T>
impl<T> UnsafeUnpin for Memo<T>where
Rc<MemoInner<T>>: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more