Some checks failed
CI / test (push) Failing after 1m42s
Adds four Criterion.rs benchmark suites to measure hot-path performance
and demonstrate the impact of Sprints 1–3 optimizations:
- benches/protocol.rs — Command & StatusMessage serialize/deserialize
- benches/bandwidth.rs — BandwidthState atomics, budget, interval math
- benches/tcp_rx_scan.rs — memchr SIMD scan vs naive O(n) loop (55× faster
on 256KB buffers with status at end)
- benches/ecsrp5.rs — WCurve::new() heavy math vs cached LazyLock
(~123,000× faster access)
Also adds BENCHMARKS.md with usage instructions and example results.
Visibility changes (bench-only):
- scan_status_message is now pub (was #[cfg(test)] only)
- WCurve and WCURVE are now pub in ecsrp5.rs
dev-dependencies: criterion + pprof (optional flamegraph support)
66 lines
2.0 KiB
Rust
66 lines
2.0 KiB
Rust
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
|
use btest_rs::protocol::{Command, StatusMessage, CMD_PROTO_TCP, CMD_DIR_BOTH};
|
|
|
|
fn bench_command_serialize(c: &mut Criterion) {
|
|
let cmd = Command::new(CMD_PROTO_TCP, CMD_DIR_BOTH);
|
|
c.bench_function("command_serialize", |b| {
|
|
b.iter(|| black_box(cmd.serialize()))
|
|
});
|
|
}
|
|
|
|
fn bench_command_deserialize(c: &mut Criterion) {
|
|
let bytes = [0x01, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
|
c.bench_function("command_deserialize", |b| {
|
|
b.iter(|| black_box(Command::deserialize(black_box(&bytes))))
|
|
});
|
|
}
|
|
|
|
fn bench_status_message_serialize(c: &mut Criterion) {
|
|
let msg = StatusMessage {
|
|
seq: 42,
|
|
bytes_received: 1_000_000,
|
|
cpu_load: 50,
|
|
};
|
|
c.bench_function("status_message_serialize", |b| {
|
|
b.iter(|| black_box(msg.serialize()))
|
|
});
|
|
}
|
|
|
|
fn bench_status_message_deserialize(c: &mut Criterion) {
|
|
let bytes = [0x07, 0xB2, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0F, 0x00];
|
|
c.bench_function("status_message_deserialize", |b| {
|
|
b.iter(|| black_box(StatusMessage::deserialize(black_box(&bytes))))
|
|
});
|
|
}
|
|
|
|
fn bench_roundtrip(c: &mut Criterion) {
|
|
let cmd = Command::new(CMD_PROTO_TCP, CMD_DIR_BOTH);
|
|
let msg = StatusMessage {
|
|
seq: 99,
|
|
bytes_received: 50_000,
|
|
cpu_load: 75,
|
|
};
|
|
c.bench_function("command_roundtrip", |b| {
|
|
b.iter(|| {
|
|
let s = black_box(cmd.serialize());
|
|
black_box(Command::deserialize(&s))
|
|
})
|
|
});
|
|
c.bench_function("status_message_roundtrip", |b| {
|
|
b.iter(|| {
|
|
let s = black_box(msg.serialize());
|
|
black_box(StatusMessage::deserialize(&s))
|
|
})
|
|
});
|
|
}
|
|
|
|
criterion_group!(
|
|
protocol_benches,
|
|
bench_command_serialize,
|
|
bench_command_deserialize,
|
|
bench_status_message_serialize,
|
|
bench_status_message_deserialize,
|
|
bench_roundtrip
|
|
);
|
|
criterion_main!(protocol_benches);
|