jam1garner / binrw

A Rust crate for helping parse and rebuild binary data using ✨macro magic✨.
https://binrw.rs
MIT License
545 stars 35 forks source link

Excessive syscalls when using BufWriter #220

Open meithecatte opened 11 months ago

meithecatte commented 11 months ago

I am writing to a BufWriter<File>. Unfortunately, std::io::BufWriter::stream_position falls back to running a seek syscall to figure out the current stream position. This makes my serialization workload take ~300x longer than necessary.

As a workaround, NoSeek<BufWriter<File>> works for my usecase. In fact, the values returned by stream_position are never used by the generated code. Emitting them only when necessary should improve the performance in many cases.

csnover commented 10 months ago

Hi, sorry for the delay. Thanks for reporting this issue, it is symmetrical to the issue with std::io::BufReader where we provide a different implementation there for the same reason.

Could you provide an example of something that that emits a stream_position call where the value is never consumed? Mostly, stream position is emitted for the sake of error handling, so there should always be a consumer of the emitted value, even if it is never used most of the time because most of the time writes don’t fail.

Thanks!

meithecatte commented 9 months ago

Hi, sorry for taking a while to get back to you. In the following example, the output of cargo expand has 3 occurrences of stream_position, always assigned to an entirely dead variable:

use binrw::binwrite;

#[binwrite]
struct Meow {
    a: u32,
    b: u32,
}

fn main() {
    println!("Hello, world!");
}

Tested with binrw@0.12.0 (latest at the time of writing).