Use buffered IO for packet processing #36

Open
opened 2025-12-07 18:43:00 +01:00 by cactusdualcore · 1 comment

In Rust, reads on a TcpStream are unbuffered, i.e. they invoke a syscall for every read. This is incredibly inefficient. See the docs of BufReader in std.

The read_packet function should ideally take a BufReader to avoid the excessive system call overhead. This may be explicit through a parameter with type &mut BufReader<TcpStream> or implicit by taking an impl Read, and providing a BufReader at all call sites. The latter allows for easier testing.

(Note that &mut R for R: std::io::Read implements Read as well, so the function should not take a reference, just an impl Read)

// lib/src/utils.rs
pub fn read_packet(mut stream: &TcpStream) -> crate::Packet {
  let mut packet_length_bits: Vec<u8> = Vec::new();
  loop {
    let buf: &mut [u8] = &mut [0];
    stream.read_exact(buf).unwrap();
    packet_length_bits.push(buf[0]);

    if buf[0] & 0x80 == 0 {
      break;
    }
  }

  // -- snip --
}
In Rust, reads on a `TcpStream` are unbuffered, i.e. they invoke a syscall for _every read_. This is **incredibly** inefficient. See the docs of [`BufReader`](https://doc.rust-lang.org/std/io/struct.BufReader.html) in `std`. The `read_packet` function should ideally take a `BufReader` to avoid the excessive system call overhead. This may be explicit through a parameter with type `&mut BufReader<TcpStream>` or implicit by taking an `impl Read`, and providing a `BufReader` at all call sites. The latter allows for easier testing. (Note that `&mut R` for `R: std::io::Read` implements `Read` as well, so the function should _not_ take a reference, just an `impl Read`) ```rust // lib/src/utils.rs pub fn read_packet(mut stream: &TcpStream) -> crate::Packet { let mut packet_length_bits: Vec<u8> = Vec::new(); loop { let buf: &mut [u8] = &mut [0]; stream.read_exact(buf).unwrap(); packet_length_bits.push(buf[0]); if buf[0] & 0x80 == 0 { break; } } // -- snip -- } ```
Owner

Good point! I remember looking into using a buffered Reader at some point, but don't remember why I didn't end up using one. If you want to, you can open a pr with your proposed changes or otherwise I will leave the issue open and look into it myself at some point in the future.

Good point! I remember looking into using a buffered Reader at some point, but don't remember why I didn't end up using one. If you want to, you can open a pr with your proposed changes or otherwise I will leave the issue open and look into it myself at some point in the future.
Sign in to join this conversation.
No description provided.