refactor: consolidate some tests/examples/benchmarks

This commit is contained in:
TechnoPorg committed 2026-02-12 23:31:19 +01:00
1 parent 49be497964
commit b8204c4ed9
83 files changed
+569 -10068

No files matched your search

-116
View File
@@ -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
View File
@@ -1,5 +1,4 @@
//! Basic DAG benchmarks - creation, execution, scaling
pub mod creation;
pub mod execution;
pub mod scaling;
-8
View File
@@ -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,
+18 -14
View File
@@ -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();
-26
View File
@@ -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();
})
});
});
}
-69
View File
@@ -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
View File
@@ -1,6 +1,5 @@
//! Realistic workload benchmarks
pub mod config_broadcast;
pub mod etl;
pub mod memory_efficiency;
pub mod mixed;