feat: dagrunner, initial version

This commit is contained in:
swaits committed 2025-10-07 16:31:03 -07:00
commit 7412287ee4
122 files changed
+23101

No files matched your search

+30
View File
@@ -0,0 +1,30 @@
//! DAG creation benchmarks
use criterion::Criterion;
use dagx::{DagRunner, Task};
use std::hint::black_box;
// Simple task for benchmarking
struct Value(i32);
#[dagx::task]
impl Value {
async fn run(&self) -> i32 {
self.0
}
}
pub fn bench_dag_creation(c: &mut Criterion) {
c.bench_function("create_empty_dag", |b| {
b.iter(|| black_box(DagRunner::new()));
});
c.bench_function("add_100_tasks", |b| {
b.iter(|| {
let dag = DagRunner::new();
for i in 0..100 {
black_box(dag.add_task(Value(i)));
}
});
});
}
+122
View File
@@ -0,0 +1,122 @@
//! Basic DAG execution benchmarks
use criterion::Criterion;
use dagx::{task_fn, DagRunner, Task};
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 |_: ()| async move { i }));
}
dag.run(|fut| {
tokio::spawn(fut);
})
.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 |_: ()| async move { i }));
}
dag.run(|fut| {
tokio::spawn(fut);
})
.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(|x: i32| async move { x + 1 }))
.depends_on(&t0);
let t2 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t1);
let t3 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t2);
let t4 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t3);
let t5 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t4);
let t6 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t5);
let t7 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t6);
let t8 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t7);
let t9 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t8);
let t10 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t9);
let t11 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t10);
let t12 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t11);
let t13 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t12);
let t14 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t13);
let t15 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t14);
let t16 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t15);
let t17 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t16);
let t18 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t17);
let _t19 = dag
.add_task(task_fn(|x: i32| async move { x + 1 }))
.depends_on(t18);
dag.run(|fut| {
tokio::spawn(fut);
})
.await
.unwrap();
})
});
});
}
+5
View File
@@ -0,0 +1,5 @@
//! Basic DAG benchmarks - creation, execution, scaling
pub mod creation;
pub mod execution;
pub mod scaling;
+32
View File
@@ -0,0 +1,32 @@
//! DAG scaling benchmarks - how performance scales with task count
use criterion::{BenchmarkId, Criterion};
use dagx::{task_fn, DagRunner};
pub fn bench_dag_scaling(c: &mut Criterion) {
let rt = tokio::runtime::Runtime::new().unwrap();
let mut group = c.benchmark_group("scaling");
// Give extra time for 1000-task benchmark (needs ~5.8s, set to 8s for headroom)
group.measurement_time(std::time::Duration::from_secs(8));
for size in [10, 50, 100, 500, 1000].iter() {
group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| {
b.iter(|| {
rt.block_on(async {
let dag = DagRunner::new();
for i in 0..size {
dag.add_task(task_fn(move |_: ()| async move { i }));
}
dag.run(|fut| {
tokio::spawn(fut);
})
.await
.unwrap();
})
});
});
}
group.finish();
}