Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/signal-chain-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ jobs:
fetch-depth: 0

- name: Configure Rust
shell: bash
run: |
rustup target add "${{ matrix.target }}" 2>/dev/null || true
rustup component add clippy 2>/dev/null || true
rustup show

- name: cargo check
Expand Down
36 changes: 13 additions & 23 deletions crates/openshell-signal-chain/benches/bench_dial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//! Note: Run `cargo bench` from the crate directory, or use:
//! cargo bench -p openshell-signal-chain

use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use openshell_signal_chain::{Dial, Room};

/// Pre-populate a room with snaps and inferences for benchmarking
Expand All @@ -21,7 +21,7 @@ fn setup_room(item_count: usize, inference_ratio: f64) -> Room {
for i in 0..snap_count {
room.add_snap(
serde_json::json!({"id": i, "type": "snap", "data": format!("snap-{}", i)}),
1.0
1.0,
);
}

Expand All @@ -30,7 +30,7 @@ fn setup_room(item_count: usize, inference_ratio: f64) -> Room {
let confidence = (i as f64) / (inference_count as f64);
room.add_inference(
serde_json::json!({"id": i, "type": "inference", "data": format!("inf-{}", i)}),
confidence.max(0.1)
confidence.max(0.1),
);
}

Expand All @@ -42,16 +42,11 @@ fn bench_dial_query(c: &mut Criterion) {

// Vary dial position
for pos in [0.0, 0.25, 0.5, 0.75, 1.0].iter() {
group.bench_with_input(
BenchmarkId::from_parameter(pos), pos,
|b, &pos| {
let room = setup_room(100, 0.5);
let dial = Dial::new(pos);
b.iter(|| {
black_box(room.query(black_box(dial)))
});
}
);
group.bench_with_input(BenchmarkId::from_parameter(pos), pos, |b, &pos| {
let room = setup_room(100, 0.5);
let dial = Dial::new(pos);
b.iter(|| black_box(room.query(black_box(dial))));
});
}

group.finish();
Expand Down Expand Up @@ -80,16 +75,11 @@ fn bench_room_scales(c: &mut Criterion) {

// Vary room size
for size in [10, 50, 100, 500, 1000].iter() {
group.bench_with_input(
BenchmarkId::from_parameter(size), size,
|b, &size| {
let room = setup_room(size, 0.5);
let dial = Dial::new(0.5);
b.iter(|| {
black_box(room.query(black_box(dial)))
});
}
);
group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| {
let room = setup_room(size, 0.5);
let dial = Dial::new(0.5);
b.iter(|| black_box(room.query(black_box(dial))));
});
}

group.finish();
Expand Down
2 changes: 1 addition & 1 deletion crates/openshell-signal-chain/benches/bench_room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//! Note: Run `cargo bench` from the crate directory, or use:
//! cargo bench -p openshell-signal-chain

use criterion::{BenchmarkId, Criterion, black_box, criterion_group, criterion_main};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use openshell_signal_chain::{Dial, Room, SignalChain};

/// Pre-populate a room with snaps and inferences for benchmarking
Expand Down
2 changes: 1 addition & 1 deletion crates/openshell-signal-chain/benches/cascade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//!
//! Run with: cargo bench -p openshell-signal-chain --bench cascade

use criterion::{BenchmarkId, Criterion, black_box, criterion_group, criterion_main};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use openshell_signal_chain::{Room, SignalChain};

/// Build a room tree of given depth and branching factor, with n inferences at the root.
Expand Down
153 changes: 111 additions & 42 deletions crates/openshell-signal-chain/benches/signal_chain_benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,32 @@
//! Criterion benchmarks for openshell-signal-chain
//! Run with: cargo bench -p openshell-signal-chain

use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
use openshell_signal_chain::{Dial, Room, SignalChain, SplineConstraint, HolonomyRoom, BettiResult};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use openshell_signal_chain::{
BettiResult, Dial, HolonomyRoom, Room, SignalChain, SplineConstraint,
};

fn bench_dial(c: &mut Criterion) {
let mut g = c.benchmark_group("Dial");
g.bench_function("new_hard", |b| b.iter(|| { let d = Dial::hard(); black_box(d.position); }));
g.bench_function("new_soft", |b| b.iter(|| { let d = Dial::soft(); black_box(d.position); }));
g.bench_function("new_hard", |b| {
b.iter(|| {
let d = Dial::hard();
black_box(d.position);
})
});
g.bench_function("new_soft", |b| {
b.iter(|| {
let d = Dial::soft();
black_box(d.position);
})
});
for pos in [0.0, 0.25, 0.5, 0.75, 1.0] {
g.bench_with_input(BenchmarkId::from_parameter(pos), &pos, |b, &p| {
b.iter(|| { let d = Dial::new(p); black_box(d.snap_weight()); black_box(d.inference_threshold()); });
b.iter(|| {
let d = Dial::new(p);
black_box(d.snap_weight());
black_box(d.inference_threshold());
});
});
}
g.finish();
Expand All @@ -24,87 +40,140 @@ fn bench_spline(c: &mut Criterion) {
let wave = SplineConstraint::new(0, 127, "wave_height_dm", 1.5, 1.5, 3.0);
for val in [10_i32, 35, 60, 90, 120] {
g.bench_with_input(BenchmarkId::from_parameter(val), &val, |b, &v| {
b.iter(|| { let d = wave.curvature_distance(v); black_box(d); });
b.iter(|| {
let d = wave.curvature_distance(v);
black_box(d);
});
});
}
g.bench_function("maritime_preset", |b| b.iter(|| {
use openshell_signal_chain::maritime_spline;
black_box(maritime_spline())
}));
g.bench_function("maritime_preset", |b| {
b.iter(|| {
use openshell_signal_chain::maritime_spline;
black_box(maritime_spline())
})
});
g.finish();
}

fn bench_room(c: &mut Criterion) {
let mut g = c.benchmark_group("Room");
g.bench_function("new", |b| b.iter(|| { let r = Room::new("t"); black_box(r); }));
g.bench_function("new", |b| {
b.iter(|| {
let r = Room::new("t");
black_box(r);
})
});

let room = {
let mut r = Room::new("t");
for i in 0..100 { r.add_snap(serde_json::json!({"i":i}), 1.0); }
for i in 0..50 { r.add_inference(serde_json::json!({"i":i}), 0.7); }
for i in 0..100 {
r.add_snap(serde_json::json!({"i":i}), 1.0);
}
for i in 0..50 {
r.add_inference(serde_json::json!({"i":i}), 0.7);
}
r
};
for d in [0.0, 0.3, 0.6, 1.0] {
g.bench_with_input(BenchmarkId::from_parameter(d), &d, |b, &p| {
b.iter(|| { let res = room.query(Dial::new(p)); black_box(res); });
b.iter(|| {
let res = room.query(Dial::new(p));
black_box(res);
});
});
}
g.finish();
}

fn bench_holonomy(c: &mut Criterion) {
let mut g = c.benchmark_group("HolonomyRoom");
let cases = vec![(3,3),(5,7),(10,17),(20,37),(4,10),(10,30)];
let cases = vec![(3, 3), (5, 7), (10, 17), (20, 37), (4, 10), (10, 30)];
for &(v, e) in &cases {
g.bench_with_input(BenchmarkId::new("betti", format!("V{}E{}",v,e)), &(v, e), |b, &(v, e)| {
b.iter(|| {
let mut r = HolonomyRoom::new("b", Dial::hard());
for _ in 0..v { r.add_snap(); }
for _ in 0..e { r.add_edge(); }
black_box(r.betti());
});
});
g.bench_with_input(
BenchmarkId::new("betti", format!("V{}E{}", v, e)),
&(v, e),
|b, &(v, e)| {
b.iter(|| {
let mut r = HolonomyRoom::new("b", Dial::hard());
for _ in 0..v {
r.add_snap();
}
for _ in 0..e {
r.add_edge();
}
black_box(r.betti());
});
},
);
}
g.bench_function("betti_pure", |b| b.iter(|| {
black_box(BettiResult::compute(17, 10, 1));
}));
g.bench_function("betti_pure", |b| {
b.iter(|| {
black_box(BettiResult::compute(17, 10, 1));
})
});
g.finish();
}

fn bench_chain(c: &mut Criterion) {
let mut g = c.benchmark_group("SignalChain");
g.bench_function("new", |b| b.iter(|| { black_box(SignalChain::new("f")); }));
g.bench_function("new", |b| {
b.iter(|| {
black_box(SignalChain::new("f"));
})
});

let chain = {
let mut ch = SignalChain::new("f");
for n in ["nav","sonar","weather","analysis"] {
for n in ["nav", "sonar", "weather", "analysis"] {
ch.room(n);
}
ch
};
for d in [0.0, 0.5, 1.0] {
g.bench_with_input(BenchmarkId::from_parameter(d), &d, |b,&p| {
b.iter(|| { black_box(chain.query_all(Dial::new(p))); });
g.bench_with_input(BenchmarkId::from_parameter(d), &d, |b, &p| {
b.iter(|| {
black_box(chain.query_all(Dial::new(p)));
});
});
}
g.bench_function("traverse", |b| b.iter(|| { black_box(chain.traverse(&["nav","sonar","weather","analysis"])); }));
g.bench_function("traverse", |b| {
b.iter(|| {
black_box(chain.traverse(&["nav", "sonar", "weather", "analysis"]));
})
});
g.finish();
}

fn bench_tput(c: &mut Criterion) {
let mut g = c.benchmark_group("Throughput");
g.bench_function("add_snap_10k", |b| b.iter(|| {
let mut r = Room::new("t");
for _ in 0..10_000 { r.add_snap(serde_json::json!({"x":1}), 1.0); }
black_box(r)
}));
g.bench_function("add_inference_10k", |b| b.iter(|| {
let mut r = Room::new("t");
for _ in 0..10_000 { r.add_inference(serde_json::json!({"x":1}), 0.75); }
black_box(r)
}));
g.bench_function("add_snap_10k", |b| {
b.iter(|| {
let mut r = Room::new("t");
for _ in 0..10_000 {
r.add_snap(serde_json::json!({"x":1}), 1.0);
}
black_box(r)
})
});
g.bench_function("add_inference_10k", |b| {
b.iter(|| {
let mut r = Room::new("t");
for _ in 0..10_000 {
r.add_inference(serde_json::json!({"x":1}), 0.75);
}
black_box(r)
})
});
g.finish();
}

criterion_group!(benches, bench_dial, bench_spline, bench_room, bench_holonomy, bench_chain, bench_tput);
criterion_group!(
benches,
bench_dial,
bench_spline,
bench_room,
bench_holonomy,
bench_chain,
bench_tput
);
criterion_main!(benches);
Loading
Loading