mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-03 08:34:07 +02:00
move benchmarks to iai-callgrind
This commit is contained in:
parent
7596677370
commit
bf4d038c8d
11 changed files with 311 additions and 299 deletions
260
benches/bench.rs
260
benches/bench.rs
|
|
@ -1,260 +0,0 @@
|
|||
use bitbuffer::{BigEndian, BitRead, BitReadBuffer, BitReadStream, Endianness, LittleEndian};
|
||||
use iai::black_box;
|
||||
|
||||
fn read_perf<E: Endianness>(buffer: &BitReadBuffer<E>) -> u16 {
|
||||
let size = 5;
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
let mut result: u16 = 0;
|
||||
loop {
|
||||
if pos + size > len {
|
||||
return result;
|
||||
}
|
||||
let data = buffer.read_int::<u64>(pos, size).unwrap() as u16;
|
||||
result = result.wrapping_add(data);
|
||||
pos += size;
|
||||
}
|
||||
}
|
||||
|
||||
const ONES: &[u8; 1024 * 1024 * 10] = &[1u8; 1024 * 1024 * 10];
|
||||
|
||||
fn perf_le() {
|
||||
let buffer = BitReadBuffer::new(black_box(ONES), BigEndian);
|
||||
let data = read_perf(&buffer);
|
||||
assert_eq!(data, 0);
|
||||
black_box(data);
|
||||
}
|
||||
|
||||
fn perf_be() {
|
||||
let buffer = BitReadBuffer::new(black_box(ONES), BigEndian);
|
||||
let data = read_perf(&buffer);
|
||||
assert_eq!(data, 0);
|
||||
black_box(data);
|
||||
}
|
||||
|
||||
fn perf_f32_be() {
|
||||
let buffer = BitReadBuffer::new(black_box(ONES), BigEndian);
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
let mut result: f32 = 0.0;
|
||||
loop {
|
||||
if pos + 32 > len {
|
||||
break;
|
||||
}
|
||||
let num = buffer.read_float::<f32>(pos).unwrap();
|
||||
result += num;
|
||||
pos += 32;
|
||||
}
|
||||
assert_eq!(result, 0.00000000000000000000000000000006170106);
|
||||
black_box(result);
|
||||
}
|
||||
|
||||
fn perf_f32_le() {
|
||||
let buffer = BitReadBuffer::new(black_box(ONES), BigEndian);
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
let mut result: f32 = 0.0;
|
||||
loop {
|
||||
if pos + 32 > len {
|
||||
break;
|
||||
}
|
||||
let num = buffer.read_float::<f32>(pos).unwrap();
|
||||
result += num;
|
||||
pos += 32;
|
||||
}
|
||||
assert_eq!(result, 0.00000000000000000000000000000006170106);
|
||||
black_box(result);
|
||||
}
|
||||
|
||||
const F64_RESULT: f64 = 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010156250477904244;
|
||||
|
||||
fn perf_f64() {
|
||||
let buffer = BitReadBuffer::new(black_box(ONES), BigEndian);
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
let mut result: f64 = 0.0;
|
||||
loop {
|
||||
if pos + 64 > len {
|
||||
break;
|
||||
}
|
||||
let num = buffer.read_float::<f64>(pos).unwrap();
|
||||
result += num;
|
||||
pos += 64;
|
||||
}
|
||||
assert_eq!(result, F64_RESULT);
|
||||
black_box(result);
|
||||
}
|
||||
|
||||
fn perf_bool() {
|
||||
let buffer = BitReadBuffer::new(black_box(ONES), BigEndian);
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
loop {
|
||||
if pos >= len {
|
||||
break;
|
||||
}
|
||||
let num = buffer.read_bool(pos).unwrap();
|
||||
black_box(num);
|
||||
pos += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const fn build_string_data<const N: usize>(inputs: &[&str]) -> [u8; N] {
|
||||
let mut data = [0; N];
|
||||
let mut i = 0;
|
||||
loop {
|
||||
let mut y = 0;
|
||||
while y < inputs.len() {
|
||||
let mut z = 0;
|
||||
let input = inputs[y].as_bytes();
|
||||
while z < input.len() {
|
||||
i += 1;
|
||||
if i >= N {
|
||||
return data;
|
||||
}
|
||||
|
||||
data[i] = input[z];
|
||||
z += 1;
|
||||
}
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const fn get_string_buffer<const N: usize>() -> [u8; N] {
|
||||
let inputs = [
|
||||
"foo\0",
|
||||
"bar\0",
|
||||
"something a little bit longer for extra testing\0",
|
||||
"a\0",
|
||||
"\0",
|
||||
];
|
||||
build_string_data::<N>(&inputs)
|
||||
}
|
||||
|
||||
const STRING_DATA: [u8; 10 * 1024] = get_string_buffer();
|
||||
|
||||
fn perf_string_be() {
|
||||
let buffer = BitReadBuffer::new(black_box(&STRING_DATA), BigEndian);
|
||||
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
loop {
|
||||
if pos + (128 * 8) > len {
|
||||
break;
|
||||
}
|
||||
let result = buffer.read_string(pos, None).unwrap();
|
||||
pos += (result.len() + 1) * 8;
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
|
||||
fn perf_string_le() {
|
||||
let buffer = BitReadBuffer::new(black_box(&STRING_DATA), LittleEndian);
|
||||
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
loop {
|
||||
if pos + (128 * 8) > len {
|
||||
break;
|
||||
}
|
||||
let result = buffer.read_string(pos, None).unwrap();
|
||||
pos += (result.len() + 1) * 8;
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
|
||||
fn perf_bytes_be() {
|
||||
let buffer = BitReadBuffer::new(black_box(&STRING_DATA), BigEndian);
|
||||
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
loop {
|
||||
if pos + (128 * 8) > len {
|
||||
break;
|
||||
}
|
||||
let result = buffer.read_bytes(pos, 128).unwrap();
|
||||
pos += (result.len() + 1) * 8;
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
|
||||
fn perf_bytes_le() {
|
||||
let buffer = BitReadBuffer::new(black_box(&STRING_DATA), LittleEndian);
|
||||
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
loop {
|
||||
if pos + (128 * 8) > len {
|
||||
break;
|
||||
}
|
||||
let result = buffer.read_bytes(pos, 128).unwrap();
|
||||
pos += (result.len() + 1) * 8;
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
|
||||
fn perf_bytes_be_unaligned() {
|
||||
let buffer = BitReadBuffer::new(black_box(&STRING_DATA), BigEndian);
|
||||
|
||||
let mut pos = 3;
|
||||
let len = buffer.bit_len();
|
||||
loop {
|
||||
if pos + (128 * 8) > len {
|
||||
break;
|
||||
}
|
||||
let result = buffer.read_bytes(pos, 128).unwrap();
|
||||
pos += (result.len() + 1) * 8;
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
|
||||
fn perf_bytes_le_unaligned() {
|
||||
let buffer = BitReadBuffer::new(black_box(&STRING_DATA), LittleEndian);
|
||||
|
||||
let mut pos = 3;
|
||||
let len = buffer.bit_len();
|
||||
loop {
|
||||
if pos + (128 * 8) > len {
|
||||
break;
|
||||
}
|
||||
let result = buffer.read_bytes(pos, 128).unwrap();
|
||||
pos += (result.len() + 1) * 8;
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(BitRead)]
|
||||
struct BasicStruct {
|
||||
a: f32,
|
||||
b: bool,
|
||||
#[size = 7]
|
||||
c: u32,
|
||||
}
|
||||
|
||||
fn perf_struct() {
|
||||
let buffer = BitReadBuffer::new(black_box(&STRING_DATA), LittleEndian);
|
||||
|
||||
let mut stream: BitReadStream<LittleEndian> = buffer.clone().into();
|
||||
while stream.bits_left() > 40 {
|
||||
let result = stream.read::<BasicStruct>().unwrap();
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
|
||||
iai::main!(
|
||||
perf_be,
|
||||
perf_bool,
|
||||
perf_bytes_be,
|
||||
perf_bytes_be_unaligned,
|
||||
perf_bytes_le,
|
||||
perf_bytes_le_unaligned,
|
||||
perf_f32_be,
|
||||
perf_f32_le,
|
||||
perf_f64,
|
||||
perf_le,
|
||||
perf_string_be,
|
||||
perf_string_le,
|
||||
perf_struct
|
||||
);
|
||||
190
benches/read.rs
Normal file
190
benches/read.rs
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
use bitbuffer::{
|
||||
BigEndian, BitRead, BitReadBuffer, BitReadStream, BitWriteStream, Endianness, LittleEndian,
|
||||
};
|
||||
use iai_callgrind::{library_benchmark, library_benchmark_group, main};
|
||||
use std::hint::black_box;
|
||||
|
||||
const ONES: &[u8; 1024 * 1024 * 10] = &[1u8; 1024 * 1024 * 10];
|
||||
|
||||
const ONES_LE: BitReadBuffer<'static, LittleEndian> = BitReadBuffer::new(ONES, LittleEndian);
|
||||
const ONES_BE: BitReadBuffer<'static, BigEndian> = BitReadBuffer::new(ONES, BigEndian);
|
||||
|
||||
#[library_benchmark]
|
||||
#[bench::le(ONES_LE)]
|
||||
#[bench::be(ONES_BE)]
|
||||
fn read_perf<E: Endianness>(buffer: BitReadBuffer<E>) -> u16 {
|
||||
let size = 5;
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
let mut result: u16 = 0;
|
||||
loop {
|
||||
if pos + size > len {
|
||||
return black_box(result);
|
||||
}
|
||||
let data = buffer.read_int::<u64>(pos, size).unwrap() as u16;
|
||||
result = result.wrapping_add(data);
|
||||
pos += size;
|
||||
}
|
||||
}
|
||||
|
||||
#[library_benchmark]
|
||||
#[bench::le(ONES_LE)]
|
||||
#[bench::be(ONES_BE)]
|
||||
fn perf_f32<E: Endianness>(buffer: BitReadBuffer<E>) -> f32 {
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
let mut result: f32 = 0.0;
|
||||
loop {
|
||||
if pos + 32 > len {
|
||||
break;
|
||||
}
|
||||
let num = buffer.read_float::<f32>(pos).unwrap();
|
||||
result += num;
|
||||
pos += 32;
|
||||
}
|
||||
assert_eq!(result, 0.00000000000000000000000000000006170106);
|
||||
black_box(result)
|
||||
}
|
||||
const F64_RESULT: f64 = 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010156250477904244;
|
||||
|
||||
#[library_benchmark]
|
||||
#[bench::le(ONES_LE)]
|
||||
#[bench::be(ONES_BE)]
|
||||
fn perf_f64<E: Endianness>(buffer: BitReadBuffer<E>) -> f64 {
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len();
|
||||
let mut result: f64 = 0.0;
|
||||
loop {
|
||||
if pos + 64 > len {
|
||||
break;
|
||||
}
|
||||
let num = buffer.read_float::<f64>(pos).unwrap();
|
||||
result += num;
|
||||
pos += 64;
|
||||
}
|
||||
assert_eq!(result, F64_RESULT);
|
||||
black_box(result)
|
||||
}
|
||||
|
||||
#[library_benchmark]
|
||||
#[bench::le(ONES_LE)]
|
||||
#[bench::be(ONES_BE)]
|
||||
fn perf_bool<E: Endianness>(buffer: BitReadBuffer<E>) {
|
||||
let mut pos = 0;
|
||||
let len = buffer.bit_len() / 8;
|
||||
loop {
|
||||
if pos >= len {
|
||||
break;
|
||||
}
|
||||
let num = buffer.read_bool(pos).unwrap();
|
||||
black_box(num);
|
||||
pos += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn build_string_buffer<E: Endianness>(
|
||||
offset: usize,
|
||||
endianness: E,
|
||||
) -> (usize, BitReadBuffer<'static, E>) {
|
||||
let mut data = Vec::new();
|
||||
let input = [
|
||||
"foo\0",
|
||||
"bar\0",
|
||||
"something a little bit longer for extra testing\0",
|
||||
"a\0",
|
||||
"\0",
|
||||
]
|
||||
.join("");
|
||||
let mut writer = BitWriteStream::new(&mut data, endianness);
|
||||
writer.write_int(0usize, offset).unwrap();
|
||||
while writer.byte_len() < 10 * 1024 {
|
||||
writer.write(&input).unwrap()
|
||||
}
|
||||
(offset, BitReadBuffer::new_owned(data, endianness))
|
||||
}
|
||||
|
||||
#[library_benchmark(setup = build_string_buffer)]
|
||||
#[bench::le_alligned(0, LittleEndian)]
|
||||
#[bench::be_alligned(0, BigEndian)]
|
||||
#[bench::le_unalligned(3, LittleEndian)]
|
||||
#[bench::be_unalligned(3, BigEndian)]
|
||||
fn perf_string<E: Endianness>((offset, buffer): (usize, BitReadBuffer<E>)) {
|
||||
let mut pos = offset;
|
||||
let len = buffer.bit_len();
|
||||
loop {
|
||||
if pos + (128 * 8) > len {
|
||||
break;
|
||||
}
|
||||
let result = buffer.read_string(pos, None).unwrap();
|
||||
pos += (result.len() + 1) * 8;
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
#[library_benchmark(setup = build_string_buffer)]
|
||||
#[bench::le_alligned(0, LittleEndian)]
|
||||
#[bench::be_alligned(0, BigEndian)]
|
||||
#[bench::le_unalligned(3, LittleEndian)]
|
||||
#[bench::be_unalligned(3, BigEndian)]
|
||||
fn perf_bytes<E: Endianness>((offset, buffer): (usize, BitReadBuffer<E>)) {
|
||||
let mut pos = offset;
|
||||
let len = buffer.bit_len();
|
||||
loop {
|
||||
if pos + (128 * 8) > len {
|
||||
break;
|
||||
}
|
||||
let result = buffer.read_bytes(pos, 128).unwrap();
|
||||
pos += (result.len() + 1) * 8;
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(BitRead)]
|
||||
struct BasicStruct {
|
||||
a: f32,
|
||||
b: bool,
|
||||
#[size = 7]
|
||||
c: u32,
|
||||
}
|
||||
|
||||
const BASIC: BasicStruct = BasicStruct {
|
||||
a: 0.0,
|
||||
b: false,
|
||||
c: 0,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(BitRead)]
|
||||
#[discriminant_bits = 2]
|
||||
enum BasicEnum {
|
||||
#[size = 5]
|
||||
Foo(i8),
|
||||
Bar(bool),
|
||||
Asd(u8),
|
||||
Empty,
|
||||
}
|
||||
|
||||
const ENUM: BasicEnum = BasicEnum::Empty;
|
||||
|
||||
#[library_benchmark]
|
||||
#[bench::le(ONES_LE, BASIC)]
|
||||
#[bench::be(ONES_BE, BASIC)]
|
||||
#[bench::le_enum(ONES_LE, ENUM)]
|
||||
#[bench::be_enum(ONES_BE, ENUM)]
|
||||
fn perf_struct<E: Endianness, Struct: BitRead<'static, E>>(
|
||||
buffer: BitReadBuffer<E>,
|
||||
_struct: Struct,
|
||||
) {
|
||||
let mut stream: BitReadStream<E> = buffer.into();
|
||||
while stream.bits_left() > 40 {
|
||||
let result = stream.read::<BasicStruct>().unwrap();
|
||||
black_box(result);
|
||||
}
|
||||
}
|
||||
|
||||
library_benchmark_group!(
|
||||
name = bench_read_group;
|
||||
benchmarks = read_perf, perf_bool, perf_bytes, perf_f32, perf_f64, perf_string, perf_struct
|
||||
);
|
||||
|
||||
main!(library_benchmark_groups = bench_read_group);
|
||||
|
|
@ -1,15 +1,35 @@
|
|||
use bitbuffer::{BitWriteStream, LittleEndian};
|
||||
use iai::black_box;
|
||||
use bitbuffer::{BigEndian, BitWriteStream, Endianness, LittleEndian};
|
||||
use iai_callgrind::{library_benchmark, library_benchmark_group, main};
|
||||
use std::hint::black_box;
|
||||
|
||||
fn write_int_le() {
|
||||
let mut out = Vec::with_capacity(128);
|
||||
fn create_output<E: Endianness>(bit_size: usize, endianness: E) -> (E, Vec<u8>, usize) {
|
||||
(
|
||||
endianness,
|
||||
Vec::with_capacity(bit_size.next_power_of_two() / 8 * 128),
|
||||
bit_size,
|
||||
)
|
||||
}
|
||||
|
||||
#[library_benchmark(setup = create_output)]
|
||||
#[bench::le_small(7, LittleEndian)]
|
||||
#[bench::be_small(7, BigEndian)]
|
||||
#[bench::le_medium(15, LittleEndian)]
|
||||
#[bench::be_medoim(15, BigEndian)]
|
||||
#[bench::le_large(57, LittleEndian)]
|
||||
#[bench::be_large(57, BigEndian)]
|
||||
fn write_int_le<E: Endianness>((endianness, mut out, bit_size): (E, Vec<u8>, usize)) {
|
||||
{
|
||||
let mut write = BitWriteStream::new(&mut out, LittleEndian);
|
||||
let mut write = BitWriteStream::new(&mut out, endianness);
|
||||
for i in 0..128 {
|
||||
write.write_sized(&black_box(i), 7).unwrap();
|
||||
write.write_sized(&black_box(i as u64), bit_size).unwrap();
|
||||
}
|
||||
}
|
||||
black_box(out);
|
||||
}
|
||||
|
||||
iai::main!(write_int_le);
|
||||
library_benchmark_group!(
|
||||
name = bench_write_group;
|
||||
benchmarks = write_int_le
|
||||
);
|
||||
|
||||
main!(library_benchmark_groups = bench_write_group);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue