Benchmarks and performance
Using criterion
+bonus if compared to other crates like nom for reading
Added some simple benchmarks to catch regressions and measure optimisations on reading
I was playing with the magic attribute and benchmarks and I realized it is very slow so I thought I would share:
#![feature(test)]
use deku::prelude::*;
#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(endian = "big", magic = b"\x00\x00\x00\x05")]
struct WithMagicV5 {
value: u32
}
#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(endian = "big")]
struct WithoutMagicV5 {
#[deku(assert = "*version == 5")]
version: u32, // users ideally should not be able to set this as it is always 5
value: u32
}
#[cfg_attr(test, macro_use)]
extern crate hex_literal;
#[cfg(test)]
mod magic_benches {
use super::*;
extern crate test;
use test::Bencher;
#[bench]
fn bench_with_magic(b: &mut Bencher) {
let data = hex!("00 00 00 05 00 00 00 01");
b.iter(|| {
let (_, _) = WithMagicV5::from_bytes((&data, 0)).unwrap();
});
}
#[bench]
fn bench_without_magic(b: &mut Bencher) {
let data = hex!("00 00 00 05 00 00 00 01");
b.iter(|| {
let (_, _) = WithoutMagicV5::from_bytes((&data, 0)).unwrap();
});
}
}
And the results:
running 2 tests
test magic_benches::bench_with_magic ... bench: 48 ns/iter (+/- 4)
test magic_benches::bench_without_magic ... bench: 21 ns/iter (+/- 6)
I was playing with the magic attribute and benchmarks and I realized it is very slow so I thought I would share:
Nice one!
There are some optimizations which could be done. This is a great example.
For example, magic attribute handling could convert the byte string to 0x00000005u32 (at compile time?) and do a single u32 read and equality check. Currently, it would do 4 u8 reads and 4 equality checks (iterating the byte string).
To add flexibility, magic could also accept a number or a bytestring!
Oh yeah, actually the first problem I faced with magic was that I couldn't pass a number (and it wasn't clear from the docs as it was a string example).
I'd be happy to give this a shot if you could give me a rough idea where to look? Seems relatively easy.
@OliverGavin Yes! That would be awesome. Happy to show you where to start.
I'd take a look at how the id attribute works, this attribute accepts both b"bytes" and tokens: https://github.com/sharksforarms/deku/blob/master/deku-derive/src/lib.rs#L17
The magic attribute is declared here: https://github.com/sharksforarms/deku/blob/master/deku-derive/src/lib.rs#L121 and as you can see only accepts a LitByteStr. This would involve changing the type to an enum to accept either b"" and other desired variants (such as LitInt)
I'll create an issue for this!
Edit: https://github.com/sharksforarms/deku/issues/204