81 lines
2.9 KiB
Rust
81 lines
2.9 KiB
Rust
//! Fan-out pattern benchmarks (1 → N dependencies)
|
|
|
|
use criterion::Criterion;
|
|
use dagx::{task_fn, DagRunner, TaskHandle};
|
|
|
|
pub fn bench_fanout(c: &mut Criterion) {
|
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
|
|
|
// Fan-out pattern (1 → n) with simple i32
|
|
c.bench_function("fanout_1_to_100_i32", |b| {
|
|
b.iter(|| {
|
|
rt.block_on(async {
|
|
let dag = DagRunner::new();
|
|
let source: TaskHandle<_> = dag.add_task(task_fn::<(), _, _>(|_: ()| 42)).into();
|
|
|
|
for i in 0..100 {
|
|
dag.add_task(task_fn::<i32, _, _>(move |&x: &i32| x + i))
|
|
.depends_on(source);
|
|
}
|
|
|
|
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
|
.await
|
|
.unwrap();
|
|
})
|
|
});
|
|
});
|
|
|
|
// Fan-out pattern with Vec (automatic Arc wrapping)
|
|
c.bench_function("fanout_1_to_100_vec", |b| {
|
|
b.iter(|| {
|
|
rt.block_on(async {
|
|
let dag = DagRunner::new();
|
|
let source: TaskHandle<_> = dag
|
|
.add_task(task_fn::<(), _, _>(|_: ()| {
|
|
// Create 1000 strings - framework wraps in Arc automatically
|
|
(0..1000).map(|i| format!("Item {}", i)).collect::<Vec<_>>()
|
|
}))
|
|
.into();
|
|
|
|
for i in 0..100 {
|
|
dag.add_task(task_fn::<Vec<_>, _, _>(move |data: &Vec<String>| {
|
|
// Each consumer gets data extracted from Arc
|
|
data.iter().filter(|s| s.contains(&i.to_string())).count()
|
|
}))
|
|
.depends_on(source);
|
|
}
|
|
|
|
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
|
.await
|
|
.unwrap();
|
|
})
|
|
});
|
|
});
|
|
|
|
// Arc overhead benchmark - shows cost on Copy types
|
|
// For Copy types like usize, Arc adds overhead (atomic refcounting + indirection)
|
|
// For heap types like Vec, Arc overhead is negligible compared to clone cost
|
|
c.bench_function("arc_overhead_copy_type", |b| {
|
|
b.iter(|| {
|
|
rt.block_on(async {
|
|
let dag = DagRunner::new();
|
|
|
|
// Source produces a simple Copy type (usize)
|
|
// Framework wraps in Arc<usize> internally
|
|
let source: TaskHandle<_> =
|
|
dag.add_task(task_fn::<(), _, _>(|_: ()| 42usize)).into();
|
|
|
|
// 100 dependents - Arc overhead visible on Copy types
|
|
for i in 0..100 {
|
|
dag.add_task(task_fn::<usize, _, _>(move |x: &usize| x + i))
|
|
.depends_on(source);
|
|
}
|
|
|
|
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
|
.await
|
|
.unwrap();
|
|
})
|
|
});
|
|
});
|
|
}
|