use criterion::{BatchSize, BenchmarkId, Criterion, criterion_group, criterion_main};
use cycle_ptr::prelude::*;
use cycle_ptr::sync::{GcMtMemberPtr, GcMtPtr, GcTask, GenerationRef, Metadata};
use std::sync::{Mutex, mpsc};
use std::thread;
use std::time::Duration;
const SIZES: [usize; 19] = [
100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000,
9000, 10000,
];
struct Child {
_parent: GcMtMemberPtr<Parent>,
}
struct Parent {
gc_metadata: Metadata,
child: Mutex<Option<GcMtMemberPtr<Child>>>,
}
fn make_test_obj() -> GcMtPtr<Parent> {
let gc_generation = GenerationRef::default();
let parent = gc_generation.make(|gc_metadata| Parent {
gc_metadata,
child: None.into(),
});
let child = gc_generation.make(|gc_metadata| Child {
_parent: gc_metadata.new_pointer(parent.clone()),
});
*parent.child.lock().unwrap() = Some(parent.gc_metadata.new_pointer(child));
parent
}
fn multithread_gc(c: &mut Criterion) {
let mut group = c.benchmark_group("multithread_gc");
for size in SIZES.into_iter() {
group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {
b.iter_batched(
|| (0..size).map(|_| make_test_obj()).collect(),
|collection: Vec<GcMtPtr<Parent>>| {
drop(collection); },
BatchSize::SmallInput,
);
});
}
group.finish();
}
fn multithread_gc_threaded(c: &mut Criterion) {
let mut group = c.benchmark_group("multithread_gc_threaded");
for size in SIZES.into_iter() {
let (pending_tx, pending_rx) = mpsc::channel::<GcTask>();
let gc_thread = thread::spawn(move || {
for task in pending_rx.iter() {
task.run();
}
});
let task_to_pending = move |task| {
pending_tx.send(task).unwrap();
};
let callback_handle =
GcTask::install_callback(&task_to_pending).expect("there should not be a callback");
group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {
b.iter_batched(
|| (0..size).map(|_| make_test_obj()).collect(),
|collection: Vec<GcMtPtr<Parent>>| {
drop(collection); },
BatchSize::SmallInput,
);
});
drop(callback_handle);
drop(task_to_pending);
let _ = gc_thread.join();
}
group.finish();
}
criterion_group!(
name = benches;
config = Criterion::default().configure_from_args().measurement_time(Duration::from_secs(10)).sample_size(50).noise_threshold(0.025);
targets = multithread_gc, multithread_gc_threaded,
);
criterion_main!(benches);