refactor: consolidate some tests/examples/benchmarks
This commit is contained in:
1 parent
49be497964
commit
b8204c4ed9
83 files changed
+569
-10068
No files matched your search
@@ -1,116 +0,0 @@
|
||||
//! Basic DAG execution benchmarks
|
||||
|
||||
use criterion::Criterion;
|
||||
use dagx::{task_fn, DagRunner};
|
||||
|
||||
pub fn bench_dag_execution(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
c.bench_function("execute_10_independent_tasks", |b| {
|
||||
b.iter(|| {
|
||||
rt.block_on(async {
|
||||
let dag = DagRunner::new();
|
||||
for i in 0..10 {
|
||||
dag.add_task(task_fn::<(), _, _>(move |_: ()| i));
|
||||
}
|
||||
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||
.await
|
||||
.unwrap();
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
c.bench_function("execute_100_independent_tasks", |b| {
|
||||
b.iter(|| {
|
||||
rt.block_on(async {
|
||||
let dag = DagRunner::new();
|
||||
for i in 0..100 {
|
||||
dag.add_task(task_fn::<(), _, _>(move |_: ()| i));
|
||||
}
|
||||
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||
.await
|
||||
.unwrap();
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
c.bench_function("execute_deep_chain_20", |b| {
|
||||
b.iter(|| {
|
||||
rt.block_on(async {
|
||||
let dag = DagRunner::new();
|
||||
|
||||
// Build a manual chain (API doesn't support loop-based chaining due to type system)
|
||||
struct Value(i32);
|
||||
#[dagx::task]
|
||||
impl Value {
|
||||
async fn run(&self) -> i32 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
let t0 = dag.add_task(Value(0));
|
||||
let t1 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t0);
|
||||
let t2 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t1);
|
||||
let t3 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t2);
|
||||
let t4 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t3);
|
||||
let t5 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t4);
|
||||
let t6 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t5);
|
||||
let t7 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t6);
|
||||
let t8 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t7);
|
||||
let t9 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t8);
|
||||
let t10 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t9);
|
||||
let t11 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t10);
|
||||
let t12 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t11);
|
||||
let t13 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t12);
|
||||
let t14 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t13);
|
||||
let t15 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t14);
|
||||
let t16 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t15);
|
||||
let t17 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t16);
|
||||
let t18 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t17);
|
||||
let _t19 = dag
|
||||
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 1))
|
||||
.depends_on(t18);
|
||||
|
||||
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||
.await
|
||||
.unwrap();
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
//! Basic DAG benchmarks - creation, execution, scaling
|
||||
|
||||
pub mod creation;
|
||||
pub mod execution;
|
||||
pub mod scaling;
|
||||
@@ -28,12 +28,6 @@ criterion_group! {
|
||||
targets = basic::creation::bench_dag_creation
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = execution_benches;
|
||||
config = configure_criterion();
|
||||
targets = basic::execution::bench_dag_execution
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = scaling_benches;
|
||||
config = configure_criterion();
|
||||
@@ -54,7 +48,6 @@ criterion_group! {
|
||||
config = configure_criterion();
|
||||
targets =
|
||||
realistic::etl::bench_etl_pipeline,
|
||||
realistic::config_broadcast::bench_config_broadcast,
|
||||
realistic::memory_efficiency::bench_memory_efficiency,
|
||||
realistic::mixed::bench_mixed_patterns
|
||||
}
|
||||
@@ -73,7 +66,6 @@ criterion_group! {
|
||||
|
||||
criterion_main!(
|
||||
creation_benches,
|
||||
execution_benches,
|
||||
scaling_benches,
|
||||
pattern_benches,
|
||||
realistic_benches,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! 10,000 task breakdown benchmarks - construction vs execution
|
||||
|
||||
use criterion::Criterion;
|
||||
use criterion::{BatchSize, Criterion};
|
||||
use dagx::{task_fn, DagRunner};
|
||||
|
||||
pub fn bench_10k_breakdown(c: &mut Criterion) {
|
||||
@@ -35,19 +35,23 @@ pub fn bench_10k_breakdown(c: &mut Criterion) {
|
||||
|
||||
// c) Execution only (pre-built DAG, just run)
|
||||
group.bench_function("execution_only", |b| {
|
||||
// Pre-build the DAG outside the measurement
|
||||
let dag = DagRunner::new();
|
||||
for i in 0..10_000 {
|
||||
dag.add_task(task_fn::<(), _, _>(move |_: ()| i));
|
||||
}
|
||||
|
||||
b.iter(|| {
|
||||
rt.block_on(async {
|
||||
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||
.await
|
||||
.unwrap();
|
||||
})
|
||||
});
|
||||
b.iter_batched(
|
||||
|| {
|
||||
let dag = DagRunner::new();
|
||||
for i in 0..10_000 {
|
||||
dag.add_task(task_fn::<(), _, _>(move |_: ()| i));
|
||||
}
|
||||
dag
|
||||
},
|
||||
|dag| {
|
||||
rt.block_on(async {
|
||||
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||
.await
|
||||
.unwrap();
|
||||
})
|
||||
},
|
||||
BatchSize::LargeInput,
|
||||
);
|
||||
});
|
||||
|
||||
group.finish();
|
||||
|
||||
@@ -51,30 +51,4 @@ pub fn bench_fanout(c: &mut Criterion) {
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
// 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();
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
//! Configuration broadcast pattern benchmark - one config shared across many workers
|
||||
|
||||
use criterion::{BenchmarkId, Criterion};
|
||||
use dagx::{task_fn, DagRunner, TaskHandle};
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::hint::black_box;
|
||||
|
||||
pub fn bench_config_broadcast(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let mut group = c.benchmark_group("config_broadcast");
|
||||
|
||||
for worker_count in [10, 50, 100, 200].iter() {
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("config", worker_count),
|
||||
worker_count,
|
||||
|b, &workers| {
|
||||
b.iter(|| {
|
||||
rt.block_on(async {
|
||||
let dag = DagRunner::new();
|
||||
|
||||
// Configuration source - framework wraps HashMap in Arc automatically
|
||||
let config: TaskHandle<_> = dag
|
||||
.add_task(task_fn::<(), _, _>(|_: ()| {
|
||||
HashMap::from([
|
||||
("max_connections".to_string(), "100".to_string()),
|
||||
("timeout_ms".to_string(), "5000".to_string()),
|
||||
("batch_size".to_string(), "50".to_string()),
|
||||
("retry_count".to_string(), "3".to_string()),
|
||||
("worker_threads".to_string(), "4".to_string()),
|
||||
("buffer_size".to_string(), "8192".to_string()),
|
||||
("compression".to_string(), "true".to_string()),
|
||||
("log_level".to_string(), "info".to_string()),
|
||||
])
|
||||
}))
|
||||
.into();
|
||||
|
||||
// Workers receive and process based on shared config
|
||||
for worker_id in 0..workers {
|
||||
dag.add_task(task_fn::<HashMap<_, _>, _, _>(
|
||||
move |cfg: &HashMap<String, String>| {
|
||||
// Simulate work based on configuration
|
||||
let batch_size: usize = cfg
|
||||
.get("batch_size")
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(10);
|
||||
let timeout: usize = cfg
|
||||
.get("timeout_ms")
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(1000);
|
||||
|
||||
// Simulate some computation
|
||||
black_box(worker_id * batch_size + timeout / 100)
|
||||
},
|
||||
))
|
||||
.depends_on(config);
|
||||
}
|
||||
|
||||
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||
.await
|
||||
.unwrap();
|
||||
})
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
//! Realistic workload benchmarks
|
||||
|
||||
pub mod config_broadcast;
|
||||
pub mod etl;
|
||||
pub mod memory_efficiency;
|
||||
pub mod mixed;
|
||||
Reference in new issue
Block a user