如何有效地从 TcpStream 读取小部分?

jz1*_*jz1 4 performance tcp rust

我正在编写一个应用程序,它将通过 TCP 连接与另一个服务进行通信。

从性能角度来看,我是一次性从所有数据中提取数据TcpStream还是一次读取各个部分的性能是否重要?比较:

fn read_byte_by_byte() {
    let mut stream = TcpStream::connect("localhost:3001").unwrap();

    let mut endian = [0; 1];
    let mut protocol = [0; 1];
    let mut msg_length = [0; 4];

    stream.read(&mut endian).unwrap();
    stream.read(&mut protocol).unwrap();
    stream.read(&mut [0; 2]).unwrap(); // throw away two padding bytes
    stream.read(&mut msg_length).unwrap();
}
Run Code Online (Sandbox Code Playgroud)
fn read_in_bulk() {
    let mut stream = TcpStream::connect("localhost:3001").unwrap();

    let mut full_msg = [0; 8];
    stream.read(&mut full_msg).unwrap();
}
Run Code Online (Sandbox Code Playgroud)

它们相等吗?或者前者的表现会更差?

Pri*_*six 6

您的问题的答案可以在以下文档中找到BufReader

BufReader<R>结构为任何读取器添加缓冲。

直接使用实例可能效率非常低Read 。例如,每次调用readonTcpStream都会导致系统调用。ABufReader<R>对底层执行大量、不频繁的读取Read,并维护结果的内存缓冲区。

BufReader<R>可以提高对同一文件或网络套接字进行小规模重复读取调用的程序的速度。当一次阅读大量内容或只阅读一次或几次时,它没有帮助。当从内存中已有的源(例如Vec<u8>.

所以是的,单独的逐字节读取调用的TcpStream性能不如批量读取,因此用 包装你TcpStreamBufReader,然后你可以按照你想要的方式读取它,而不会对性能造成重大损失。