mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-03 16:44:06 +02:00
inline count check
This commit is contained in:
parent
f1d1737cd9
commit
8342290cc6
2 changed files with 23 additions and 12 deletions
|
|
@ -2,9 +2,8 @@
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use test::Bencher;
|
|
||||||
use bitstream_reader::{BitBuffer, LittleEndian};
|
use bitstream_reader::{BitBuffer, LittleEndian};
|
||||||
|
use test::Bencher;
|
||||||
|
|
||||||
fn read_perf(buffer: &BitBuffer<LittleEndian>) -> u16 {
|
fn read_perf(buffer: &BitBuffer<LittleEndian>) -> u16 {
|
||||||
let size = 5;
|
let size = 5;
|
||||||
|
|
@ -23,11 +22,11 @@ fn read_perf(buffer: &BitBuffer<LittleEndian>) -> u16 {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn perf_non_padded(b: &mut Bencher) {
|
fn perf_non_padded(b: &mut Bencher) {
|
||||||
let file = fs::read("/bulk/tmp/test.dem").expect("Unable to read file");
|
let data = vec![1u8; 1024 * 1024 * 10];
|
||||||
let buffer = BitBuffer::new(file, LittleEndian);
|
let buffer = BitBuffer::new(data, LittleEndian);
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let data = read_perf(&buffer);
|
let data = read_perf(&buffer);
|
||||||
assert_eq!(data, 43943);
|
assert_eq!(data, 0);
|
||||||
test::black_box(data);
|
test::black_box(data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -176,20 +176,32 @@ where
|
||||||
///
|
///
|
||||||
/// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
|
/// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
|
||||||
/// [`ReadError::TooManyBits`]: enum.ReadError.html#variant.TooManyBits
|
/// [`ReadError::TooManyBits`]: enum.ReadError.html#variant.TooManyBits
|
||||||
|
#[inline]
|
||||||
pub fn read_int<T>(&self, position: usize, count: usize) -> Result<T>
|
pub fn read_int<T>(&self, position: usize, count: usize) -> Result<T>
|
||||||
where
|
where
|
||||||
T: PrimInt + BitOrAssign + IsSigned + UncheckedPrimitiveInt,
|
T: PrimInt + BitOrAssign + IsSigned + UncheckedPrimitiveInt,
|
||||||
{
|
{
|
||||||
let value = {
|
|
||||||
let type_bit_size = size_of::<T>() * 8;
|
let type_bit_size = size_of::<T>() * 8;
|
||||||
let usize_bit_size = size_of::<usize>() * 8;
|
|
||||||
|
|
||||||
|
// by splitting of the count check and the actual reading
|
||||||
|
// we can inline the count check (which get's resolved at compile time if a constant count is used)
|
||||||
|
// without having to pay the potentional cost of inlining a larger function
|
||||||
if type_bit_size < count {
|
if type_bit_size < count {
|
||||||
return Err(ReadError::TooManyBits {
|
return Err(ReadError::TooManyBits {
|
||||||
requested: count,
|
requested: count,
|
||||||
max: type_bit_size,
|
max: type_bit_size,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
self.read_int_no_count_check(position, count)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_int_no_count_check<T>(&self, position: usize, count: usize) -> Result<T>
|
||||||
|
where
|
||||||
|
T: PrimInt + BitOrAssign + IsSigned + UncheckedPrimitiveInt,
|
||||||
|
{
|
||||||
|
let value = {
|
||||||
|
let type_bit_size = size_of::<T>() * 8;
|
||||||
|
let usize_bit_size = size_of::<usize>() * 8;
|
||||||
|
|
||||||
if position + count > self.bit_len {
|
if position + count > self.bit_len {
|
||||||
if position > self.bit_len {
|
if position > self.bit_len {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue