在Rust中迭代文件字节的更快方法是什么?

我是 Rust 的新手,我正在尝试想出一个简单的备份程序。第一步,文件被分解成可变长度的块(通过内容定义的分块)。

为此,我必须逐字节读取文件。不幸的是,我发现这个过程非常缓慢。随着dd我能够以高达350 MIB读取/秒。尽管如此,使用以下 Rust 代码我只能得到大约 45 MiB/s。(我省略了那里的所有分块内容。

我正在阅读的文件大小约为 7.7 GiB。

// main.rs


use std::fs::File;
use std::io::BufReader;
use std::io::{Read, Bytes};
use std::time::{Instant, Duration};

fn main() {
    let file = File::open("something_big.tar").expect("Cannot read file.");
    
    let mut buf = BufReader::new(file);

    let mut x = 0u8;

    let mut num_bytes = 0usize;

    let t1 = Instant::now();

    for b in buf.bytes() {
        match b {
            Ok(b) => {
                x += b;
                num_bytes += 1;
                // chunking stuff omitted
            },
            Err(_) => panic!("I/O Error")
        }
    }

    let dur = t1.elapsed().as_secs_f64();
    let mut num_bytes = (num_bytes as f64) / 1_048_576f64;

    println!("RESULT: {}", x);

    println!("Read speed: {:.1} MiB / s", num_bytes / dur);
}

问题:使用 Rust快速迭代文件字节的更好方法是什么?我的代码有什么问题?

我知道也许我可以使用memmap板条箱或类似的东西——但是:我不想那样做。

回答

我不确定为什么会发生这种情况,但是read()BufReader. 使用下面的 512 字节数组,我看到 ~2700MiB/s,单字节数组约为 300 MiB/s。

Bytes迭代器显然引起一些开销,这种实现是或多或少复制其粘贴IntoIterator实现。

use std::fs::File;
use std::io::{BufReader, ErrorKind};
use std::io::Read;
use std::time::Instant;

fn main() {
    let file = File::open("some-3.3gb-file")
        .expect("Cannot read file.");

    let mut buf = BufReader::new(file);

    let mut x = 0u8;

    let mut num_bytes = 0usize;

    let t1 = Instant::now();

    let mut bytes = [0; 512];
    loop {
        match buf.read(&mut bytes) {
            Ok(0) => break,
            Ok(n) => {
                for i in 0..n {
                    num_bytes += 1;
                    x += bytes[i];
                }
            }
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => panic!("{:?}", e),
        };
    }

    let dur = t1.elapsed().as_secs_f64();
    let mut num_bytes = (num_bytes as f64) / 1_048_576f64;

    println!("RESULT: {}", x);

    println!("Read speed: {:.1} MiB / s for {}", num_bytes / dur, num_bytes);
}


以上是在Rust中迭代文件字节的更快方法是什么?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>