use criterion::{BatchSize, BenchmarkId, Criterion, criterion_group, criterion_main};
use lencode::io::{Cursor, Read, VecWriter, Write};
use std::hint::black_box;
fn bench_cursor_read(c: &mut Criterion) {
let mut group = c.benchmark_group("cursor_read");
group.bench_function("buf", |b| {
let backing = [0u8; 256];
b.iter_batched(
|| Cursor::new(black_box(backing)),
|cursor| {
let cursor = black_box(cursor);
black_box(cursor.buf());
},
BatchSize::SmallInput,
)
});
group.bench_function("advance_8", |b| {
let backing = [0u8; 256];
b.iter_batched(
|| Cursor::new(black_box(backing)),
|cursor| {
let mut cursor = black_box(cursor);
cursor.advance(8);
black_box(cursor);
},
BatchSize::SmallInput,
)
});
for &len in &[1usize, 4, 8, 16, 32, 64, 256] {
group.bench_with_input(BenchmarkId::new("read_into", len), &len, |b, &len| {
let backing = [0u8; 256];
b.iter_batched(
|| (Cursor::new(black_box(backing)), [0u8; 256]),
|(mut cursor, mut dst)| {
let _ = cursor.read(&mut dst[..len]).unwrap();
black_box(dst);
},
BatchSize::SmallInput,
)
});
}
group.bench_function("buf_advance_loop_32", |b| {
let backing = [0u8; 256];
b.iter_batched(
|| Cursor::new(black_box(backing)),
|cursor| {
let mut cursor = black_box(cursor);
let mut sum: u32 = 0;
for _ in 0..32 {
let slice = cursor.buf().unwrap();
sum = sum.wrapping_add(slice[0] as u32);
cursor.advance(1);
}
black_box(sum);
},
BatchSize::SmallInput,
)
});
group.bench_function("buf_memcpy_advance_8", |b| {
let backing = [0u8; 256];
b.iter_batched(
|| (Cursor::new(black_box(backing)), [0u8; 8]),
|(mut cursor, mut dst)| {
let cursor_ref = &mut cursor;
let slice = cursor_ref.buf().unwrap();
dst.copy_from_slice(&slice[..8]);
cursor_ref.advance(8);
black_box(dst);
},
BatchSize::SmallInput,
)
});
group.finish();
}
fn bench_cursor_write(c: &mut Criterion) {
let mut group = c.benchmark_group("cursor_write");
group.bench_function("buf_mut", |b| {
b.iter_batched(
|| Cursor::new(black_box([0u8; 256])),
|cursor| {
let mut cursor = black_box(cursor);
black_box(cursor.buf_mut());
},
BatchSize::SmallInput,
)
});
group.bench_function("advance_mut_8", |b| {
b.iter_batched(
|| Cursor::new(black_box([0u8; 256])),
|cursor| {
let mut cursor = black_box(cursor);
cursor.advance_mut(8);
black_box(cursor);
},
BatchSize::SmallInput,
)
});
for &len in &[1usize, 4, 8, 16, 32, 64, 256] {
group.bench_with_input(BenchmarkId::new("write", len), &len, |b, &len| {
let src = [0xAAu8; 256];
b.iter_batched(
|| Cursor::new([0u8; 256]),
|cursor| {
let mut cursor = black_box(cursor);
let _ = cursor.write(black_box(&src[..len])).unwrap();
black_box(cursor);
},
BatchSize::SmallInput,
)
});
}
group.bench_function("buf_mut_memcpy_advance_8", |b| {
let src = [0xAAu8; 8];
b.iter_batched(
|| Cursor::new([0u8; 256]),
|cursor| {
let mut cursor = black_box(cursor);
let dst = cursor.buf_mut().unwrap();
dst[..8].copy_from_slice(black_box(&src));
cursor.advance_mut(8);
black_box(cursor);
},
BatchSize::SmallInput,
)
});
group.finish();
}
fn bench_vec_writer(c: &mut Criterion) {
let mut group = c.benchmark_group("vec_writer");
group.bench_function("new", |b| {
b.iter(|| {
black_box(VecWriter::new());
})
});
group.bench_function("first_buf_mut", |b| {
b.iter_batched(
VecWriter::new,
|writer| {
let mut writer = black_box(writer);
black_box(writer.buf_mut());
},
BatchSize::SmallInput,
)
});
for &len in &[1usize, 4, 8, 16, 32, 64, 256, 1024] {
group.bench_with_input(BenchmarkId::new("write_fresh", len), &len, |b, &len| {
let src = [0xAAu8; 1024];
b.iter_batched(
VecWriter::new,
|mut writer| {
let _ = writer.write(black_box(&src[..len])).unwrap();
black_box(writer);
},
BatchSize::SmallInput,
)
});
}
group.bench_function("varint_pattern_8x9", |b| {
let chunk = [0xAAu8; 9];
b.iter_batched(
VecWriter::new,
|mut writer| {
for _ in 0..8 {
let dst = writer.buf_mut().unwrap();
dst[..9].copy_from_slice(black_box(&chunk));
writer.advance_mut(9);
}
black_box(writer);
},
BatchSize::SmallInput,
)
});
group.bench_function("varint_pattern_8x9_prereserved", |b| {
let chunk = [0xAAu8; 9];
b.iter_batched(
|| VecWriter::with_capacity(128),
|mut writer| {
for _ in 0..8 {
let dst = writer.buf_mut().unwrap();
dst[..9].copy_from_slice(black_box(&chunk));
writer.advance_mut(9);
}
black_box(writer);
},
BatchSize::SmallInput,
)
});
group.bench_function("growth_2048_via_writes_64", |b| {
let chunk = [0xAAu8; 64];
b.iter_batched(
VecWriter::new,
|mut writer| {
for _ in 0..32 {
let _ = writer.write(black_box(&chunk)).unwrap();
}
black_box(writer);
},
BatchSize::SmallInput,
)
});
group.bench_function("growth_2048_prereserved", |b| {
let chunk = [0xAAu8; 64];
b.iter_batched(
|| VecWriter::with_capacity(2048),
|mut writer| {
for _ in 0..32 {
let _ = writer.write(black_box(&chunk)).unwrap();
}
black_box(writer);
},
BatchSize::SmallInput,
)
});
group.bench_function("into_inner", |b| {
b.iter_batched(
VecWriter::new,
|writer| {
let writer = black_box(writer);
black_box(writer.into_inner());
},
BatchSize::SmallInput,
)
});
group.finish();
}
criterion_group!(
benches,
bench_cursor_read,
bench_cursor_write,
bench_vec_writer
);
criterion_main!(benches);