use criterion::{criterion_group, criterion_main, Criterion};
use std::hint::black_box;
use a2a_protocol_client::streaming::SseParser;
fn make_sse_payload(n_events: usize) -> Vec<u8> {
let mut buf = Vec::new();
for i in 0..n_events {
let data = format!(
"data: {{\"kind\":\"status-update\",\"taskId\":\"task-{i}\",\"contextId\":\"ctx-1\",\"status\":{{\"state\":\"TASK_STATE_WORKING\"}}}}\n\n"
);
buf.extend_from_slice(data.as_bytes());
}
buf
}
fn bench_sse_parse_single(c: &mut Criterion) {
let payload = make_sse_payload(1);
c.bench_function("sse_parse_single_event", |b| {
b.iter(|| {
let mut parser = SseParser::default();
parser.feed(black_box(&payload));
let mut count = 0u32;
while parser.next_frame().is_some() {
count += 1;
}
debug_assert_eq!(count, 1);
});
});
}
fn bench_sse_parse_batch(c: &mut Criterion) {
let payload = make_sse_payload(100);
c.bench_function("sse_parse_100_events", |b| {
b.iter(|| {
let mut parser = SseParser::default();
parser.feed(black_box(&payload));
let mut count = 0;
while parser.next_frame().is_some() {
count += 1;
}
assert_eq!(count, 100);
});
});
}
fn bench_sse_parse_fragmented(c: &mut Criterion) {
let payload = make_sse_payload(10);
c.bench_function("sse_parse_fragmented_delivery", |b| {
b.iter(|| {
let mut parser = SseParser::default();
for byte in black_box(&payload) {
parser.feed(std::slice::from_ref(byte));
}
let mut count = 0;
while parser.next_frame().is_some() {
count += 1;
}
assert_eq!(count, 10);
});
});
}
criterion_group!(
benches,
bench_sse_parse_single,
bench_sse_parse_batch,
bench_sse_parse_fragmented,
);
criterion_main!(benches);