Module binrw::docs::performance

source ·
Expand description

Tips for high performance parsing and serialisation.

Use buffered inputs

During parsing, binrw regularly queries the position of the input stream to provide byte- and field-accurate error reporting. It will also rewind the stream when an enum variant fails to parse to try the next one, or when unrecoverable errors occur to leave the input stream in a consistent state.

In-memory streams like std::io::Cursor have no problem with this access pattern, but others like std::fs::File may be unexpectedly slow due to system call overhead. To improve performance of these stream types, simply wrap them with BufReader.

std::io::BufReader from the standard library invalidates its buffer every time a seek occurs so may make performance worse. Use only the binrw wrapper or some other alternative that does not invalidate its internal buffer on seek.

Most common enum variants first

binrw parsing starts at the top of an enum and works its way down the list of variants until one of them parses successfully. Putting the most common variants first will reduce the amount of work binrw needs to do to parse an enum.

Discard enum errors

When parsing an enum, binrw generates an Error for each variant that fails parsing. By default, these errors are all collected in a Vec until one variant parses successfully (at which point they are discarded) or until parsing fails (at which point they are passed to the caller).

The #[br(return_unexpected_error)] directive stops binrw from collecting any variant parsing errors, which eliminates extra work spent allocating and freeing memory for storing errors. The downside is that only the stream position can be provided when an enum fails to parse because the errors were thrown away.

Use specific types for faster block I/O

To improve performance when reading or writing large blocks of data, binrw uses a fake specialisation technique to generate optimised I/O calls for certain types:

TypeReadWrite
Vec<u8>yesyes
Vec<i8>yesyes
Vec<u16>yesno
Vec<i16>yesno
Vec<u32>yesno
Vec<i32>yesno
Vec<u64>yesno
Vec<i64>yesno
Vec<u128>yesno
Vec<i128>yesno
[u8; N]noyes
Box<[u8]>noyes