use dync::{SmallValue, VecDrop};
use dync_derive::dync_trait;
use std::collections::HashMap;
use std::rc::Rc;
use std::time::Instant;
use rand::distributions::Alphanumeric;
use rand::prelude::*;
#[dync_trait]
trait HTValue: Clone + PartialEq + Eq + std::hash::Hash + std::fmt::Debug {}
impl<T> HTValue for T where T: Clone + PartialEq + Eq + std::hash::Hash + std::fmt::Debug {}
type VecDropCached = VecDrop<HTValueVTable>;
fn costly_computation_int(seed: u8) -> [u128; 3] {
let mut rng: StdRng = SeedableRng::from_seed([seed; 32]);
[rng.gen(), rng.gen(), rng.gen()]
}
fn costly_computation_str(seed: u8) -> String {
let rng: StdRng = SeedableRng::from_seed([seed; 32]);
rng.sample_iter(&Alphanumeric).take(30).collect()
}
fn main() {
let mut rng: StdRng = SeedableRng::from_seed([3; 32]);
{
let mut int_values = VecDropCached::with_type::<[u128; 3]>();
let mut str_values = VecDropCached::with_type::<String>();
let start_time = Instant::now();
for _ in 0..50_000 {
let seed = rng.gen::<u8>();
int_values.push_as(costly_computation_int(seed));
str_values.push_as(costly_computation_str(seed));
}
println!(
"non cached loop: {} milliseconds",
start_time.elapsed().as_millis()
);
}
{
let mut cache = HashMap::<u8, SmallValue<HTValueVTable>>::new();
let mut int_values = VecDropCached::with_type::<Rc<[u128; 3]>>();
let mut str_values = VecDropCached::with_type::<Rc<String>>();
let start_time = Instant::now();
for _ in 0..50_000 {
let seed = rng.gen::<u8>();
let int_value = cache
.entry(seed)
.or_insert_with(|| SmallValue::new(Rc::new(costly_computation_int(seed))));
int_values.push_cloned(int_value.as_ref());
let str_value = cache
.entry(seed)
.or_insert_with(|| SmallValue::new(Rc::new(costly_computation_int(seed))));
str_values.push_cloned(str_value.as_ref());
}
println!(
"cached loop: {} milliseconds",
start_time.elapsed().as_millis()
);
}
}