1
0
Fork 0
mirror of https://codeberg.org/icewind/bitbuffer.git synced 2026-06-03 16:44:06 +02:00

move benches to iai

This commit is contained in:
Robin Appelman 2021-07-18 19:55:45 +02:00
commit 94bc320add
3 changed files with 188 additions and 210 deletions

View file

@ -15,5 +15,10 @@ memchr = "2"
[dev-dependencies] [dev-dependencies]
maplit = "1" maplit = "1"
iai = "0.1"
[[bench]]
name = "bench"
harness = false
[workspace] [workspace]

View file

@ -1,9 +1,5 @@
#![feature(test)]
extern crate test;
use bitbuffer::{BigEndian, BitRead, BitReadBuffer, BitReadStream, Endianness, LittleEndian}; use bitbuffer::{BigEndian, BitRead, BitReadBuffer, BitReadStream, Endianness, LittleEndian};
use test::Bencher; use iai::black_box;
fn read_perf<E: Endianness>(buffer: &BitReadBuffer<E>) -> u16 { fn read_perf<E: Endianness>(buffer: &BitReadBuffer<E>) -> u16 {
let size = 5; let size = 5;
@ -20,247 +16,212 @@ fn read_perf<E: Endianness>(buffer: &BitReadBuffer<E>) -> u16 {
} }
} }
#[bench] const ONES: [u8; 1024 * 1024 * 10] = [1u8; 1024 * 1024 * 10];
fn perf_le(b: &mut Bencher) {
let data = vec![1u8; 1024 * 1024 * 10]; fn perf_le() {
let buffer = BitReadBuffer::new(&data, LittleEndian); let buffer = BitReadBuffer::new(black_box(&ONES), BigEndian);
b.iter(|| { let data = read_perf(&buffer);
let data = read_perf(&buffer); assert_eq!(data, 0);
assert_eq!(data, 0); black_box(data);
test::black_box(data);
});
} }
#[bench] fn perf_be() {
fn perf_be(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&ONES), BigEndian);
let data = vec![1u8; 1024 * 1024 * 10]; let data = read_perf(&buffer);
let buffer = BitReadBuffer::new(&data, BigEndian); assert_eq!(data, 0);
b.iter(|| { black_box(data);
let data = read_perf(&buffer);
assert_eq!(data, 0);
test::black_box(data);
});
} }
#[bench] fn perf_f32_be() {
fn perf_f32_be(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&ONES), BigEndian);
let data = vec![1u8; 1024 * 1024 * 10]; let mut pos = 0;
let buffer = BitReadBuffer::new(&data, BigEndian); let len = buffer.bit_len();
b.iter(|| { let mut result: f32 = 0.0;
let mut pos = 0; loop {
let len = buffer.bit_len(); if pos + 32 > len {
let mut result: f32 = 0.0; break;
loop {
if pos + 32 > len {
break;
}
let num = buffer.read_float::<f32>(pos).unwrap();
result += num;
pos += 32;
} }
assert_eq!(result, 0.00000000000000000000000000000006170106); let num = buffer.read_float::<f32>(pos).unwrap();
test::black_box(result); result += num;
}); pos += 32;
}
assert_eq!(result, 0.00000000000000000000000000000006170106);
black_box(result);
} }
#[bench] fn perf_f32_le() {
fn perf_f32_le(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&ONES), BigEndian);
let data = vec![1u8; 1024 * 1024 * 10]; let mut pos = 0;
let buffer = BitReadBuffer::new(&data, LittleEndian); let len = buffer.bit_len();
b.iter(|| { let mut result: f32 = 0.0;
let mut pos = 0; loop {
let len = buffer.bit_len(); if pos + 32 > len {
let mut result: f32 = 0.0; break;
loop {
if pos + 32 > len {
break;
}
let num = buffer.read_float::<f32>(pos).unwrap();
result += num;
pos += 32;
} }
assert_eq!(result, 0.00000000000000000000000000000006170106); let num = buffer.read_float::<f32>(pos).unwrap();
test::black_box(result); result += num;
}); pos += 32;
}
assert_eq!(result, 0.00000000000000000000000000000006170106);
black_box(result);
} }
const F64_RESULT: f64 = 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010156250477904244; const F64_RESULT: f64 = 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010156250477904244;
#[bench] fn perf_f64() {
fn perf_f64(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&ONES), BigEndian);
let data = vec![1u8; 1024 * 1024 * 10]; let mut pos = 0;
let buffer = BitReadBuffer::new(&data, BigEndian); let len = buffer.bit_len();
b.iter(|| { let mut result: f64 = 0.0;
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);
test::black_box(result);
});
}
#[bench]
fn perf_bool(b: &mut Bencher) {
let data = vec![1u8; 1024 * 1024 * 1];
let buffer = BitReadBuffer::new(&data, BigEndian);
b.iter(|| {
let mut pos = 0;
let len = buffer.bit_len();
loop {
if pos >= len {
break;
}
let num = buffer.read_bool(pos).unwrap();
test::black_box(num);
pos += 1;
}
});
}
fn build_string_data(size: usize, inputs: &Vec<&str>) -> Vec<u8> {
let mut data = Vec::with_capacity(size);
loop { loop {
for input in inputs.iter() { if pos + 64 > len {
if data.len() + input.len() + 1 >= size { break;
return data; }
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;
} }
data.extend_from_slice(input.as_bytes()); y += 1;
data.push(0);
} }
} }
} }
fn get_string_buffer() -> Vec<u8> { const fn get_string_buffer<const N: usize>() -> [u8; N] {
let inputs = vec![ let inputs = [
"foo", "foo\0",
"bar", "bar\0",
"something a little bit longer for extra testing", "something a little bit longer for extra testing\0",
"a", "a\0",
"", "\0",
]; ];
build_string_data(10 * 1024 * 1024, &inputs) build_string_data::<N>(&inputs)
} }
#[bench] const STRING_DATA: [u8; 10 * 1024] = get_string_buffer();
fn perf_string_be(b: &mut Bencher) {
let data = get_string_buffer();
let buffer = BitReadBuffer::new(&data, BigEndian);
b.iter(|| { fn perf_string_be() {
let mut pos = 0; let buffer = BitReadBuffer::new(black_box(&STRING_DATA), BigEndian);
let len = buffer.bit_len();
loop { let mut pos = 0;
if pos + (128 * 8) > len { let len = buffer.bit_len();
break; loop {
} if pos + (128 * 8) > len {
let result = buffer.read_string(pos, None).unwrap(); break;
pos += (result.len() + 1) * 8;
test::black_box(result);
} }
}); let result = buffer.read_string(pos, None).unwrap();
pos += (result.len() + 1) * 8;
black_box(result);
}
} }
#[bench] fn perf_string_le() {
fn perf_string_le(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&STRING_DATA), LittleEndian);
let data = get_string_buffer();
let buffer = BitReadBuffer::new(&data, LittleEndian);
b.iter(|| { let mut pos = 0;
let mut pos = 0; let len = buffer.bit_len();
let len = buffer.bit_len(); loop {
loop { if pos + (128 * 8) > len {
if pos + (128 * 8) > len { break;
break;
}
let result = buffer.read_string(pos, None).unwrap();
pos += (result.len() + 1) * 8;
test::black_box(result);
} }
}); let result = buffer.read_string(pos, None).unwrap();
pos += (result.len() + 1) * 8;
black_box(result);
}
} }
#[bench] fn perf_bytes_be() {
fn perf_bytes_be(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&STRING_DATA), BigEndian);
let data = get_string_buffer();
let buffer = BitReadBuffer::new(&data, BigEndian);
b.iter(|| { let mut pos = 0;
let mut pos = 0; let len = buffer.bit_len();
let len = buffer.bit_len(); loop {
loop { if pos + (128 * 8) > len {
if pos + (128 * 8) > len { break;
break;
}
let result = buffer.read_bytes(pos, 128).unwrap();
pos += (result.len() + 1) * 8;
test::black_box(result);
} }
}); let result = buffer.read_bytes(pos, 128).unwrap();
pos += (result.len() + 1) * 8;
black_box(result);
}
} }
#[bench] fn perf_bytes_le() {
fn perf_bytes_le(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&STRING_DATA), LittleEndian);
let data = get_string_buffer();
let buffer = BitReadBuffer::new(&data, LittleEndian);
b.iter(|| { let mut pos = 0;
let mut pos = 0; let len = buffer.bit_len();
let len = buffer.bit_len(); loop {
loop { if pos + (128 * 8) > len {
if pos + (128 * 8) > len { break;
break;
}
let result = buffer.read_bytes(pos, 128).unwrap();
pos += (result.len() + 1) * 8;
test::black_box(result);
} }
}); let result = buffer.read_bytes(pos, 128).unwrap();
pos += (result.len() + 1) * 8;
black_box(result);
}
} }
#[bench] fn perf_bytes_be_unaligned() {
fn perf_bytes_be_unaligned(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&STRING_DATA), BigEndian);
let data = get_string_buffer();
let buffer = BitReadBuffer::new(&data, BigEndian);
b.iter(|| { let mut pos = 3;
let mut pos = 3; let len = buffer.bit_len();
let len = buffer.bit_len(); loop {
loop { if pos + (128 * 8) > len {
if pos + (128 * 8) > len { break;
break;
}
let result = buffer.read_bytes(pos, 128).unwrap();
pos += (result.len() + 1) * 8;
test::black_box(result);
} }
}); let result = buffer.read_bytes(pos, 128).unwrap();
pos += (result.len() + 1) * 8;
black_box(result);
}
} }
#[bench] fn perf_bytes_le_unaligned() {
fn perf_bytes_le_unaligned(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&STRING_DATA), LittleEndian);
let data = get_string_buffer();
let buffer = BitReadBuffer::new(&data, LittleEndian);
b.iter(|| { let mut pos = 3;
let mut pos = 3; let len = buffer.bit_len();
let len = buffer.bit_len(); loop {
loop { if pos + (128 * 8) > len {
if pos + (128 * 8) > len { break;
break;
}
let result = buffer.read_bytes(pos, 128).unwrap();
pos += (result.len() + 1) * 8;
test::black_box(result);
} }
}); let result = buffer.read_bytes(pos, 128).unwrap();
pos += (result.len() + 1) * 8;
black_box(result);
}
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -272,16 +233,28 @@ struct BasicStruct {
c: u32, c: u32,
} }
#[bench] fn perf_struct() {
fn perf_struct(b: &mut Bencher) { let buffer = BitReadBuffer::new(black_box(&STRING_DATA), LittleEndian);
let data = get_string_buffer();
let buffer = BitReadBuffer::new(&data, LittleEndian);
b.iter(|| { let mut stream: BitReadStream<LittleEndian> = buffer.clone().into();
let mut stream: BitReadStream<LittleEndian> = buffer.clone().into(); while stream.bits_left() > 40 {
while stream.bits_left() > 40 { let result = stream.read::<BasicStruct>().unwrap();
let result = stream.read::<BasicStruct>().unwrap(); black_box(result);
test::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
);

View file

@ -362,7 +362,7 @@ where
}); });
} }
if position + count + USIZE_BIT_SIZE > self.bit_len() { if position + USIZE_BIT_SIZE > self.bit_len() {
if position + count > self.bit_len() { if position + count > self.bit_len() {
return if position > self.bit_len() { return if position > self.bit_len() {
Err(BitError::IndexOutOfBounds { Err(BitError::IndexOutOfBounds {
@ -712,7 +712,7 @@ where
T: Float + UncheckedPrimitiveFloat, T: Float + UncheckedPrimitiveFloat,
{ {
let type_bit_size = size_of::<T>() * 8; let type_bit_size = size_of::<T>() * 8;
if position + type_bit_size + USIZE_BIT_SIZE > self.bit_len() { if position + USIZE_BIT_SIZE > self.bit_len() {
if position + type_bit_size > self.bit_len() { if position + type_bit_size > self.bit_len() {
if position > self.bit_len() { if position > self.bit_len() {
return Err(BitError::IndexOutOfBounds { return Err(BitError::IndexOutOfBounds {