为什么当我迭代 Rust 中的迭代器时它们看起来非常慢?

Why are iterators in Rust seemingly very slow when I iterate over them?

我正在使用 mmap 读取一个大文件。我想在每一行上做一些操作,所以我在上面调用了 split() ,它为每一行提供了一个迭代器:

let file = File::open("myfile").unwrap();
let mmap = unsafe { MmapOptions::new().map(&file).unwrap() };
//splitting by newline
let iter = mmap.split(|elem| elem == &b'\n');

这很好用,没有给我任何问题 - 运行速度非常快。

但是,当我遍历迭代器时,它跳转并且遍历 for 循环是读取和拆分所用时间的 4 倍左右。

此外,这没有处理该行或在 for 循环内执行任何操作:

for elem in iter {
  //process the line
}

由于性能是一个问题 - 我觉得奇怪的是它设法非常快地读取和拆分文件,但是,当我通过迭代器时它变得非常慢。我错过了什么吗?我对生锈的了解也很有限,所以不确定我是否在做坏事。有什么可以帮助我优化它并加快访问速度的吗?

此外,并行迭代器对我的情况没有太大帮助 - 它们增加的开销不值得。

整个文件:

use memmap::MmapOptions;
use std::fs::File;
use std::time::{Duration, Instant};

fn main() {

    let now = Instant::now();
    let file = File::open("myfile").unwrap();
    let mmap = unsafe { MmapOptions::new().map(&file).unwrap() };
    let iter = mmap.split(|elem| elem == &b'\n');

    /*
    for elem in iter {
      //do nothing
    }
    */
    println!("{:?}", now.elapsed());
}

如果我取消注释 for 循环,它会慢 4 倍。我正在使用 --release 标签进行构建,所以这不是问题。

代码只有在取消注释 for 循环时才看起来很慢,因为 它不会做任何事情 否则。 迭代器是惰性的,只在使用时执行一些activity。

引用Rust Programming language, chapter 13, section 2中的相关部分:

In Rust, iterators are lazy, meaning they have no effect until you call methods that consume the iterator to use it up. [...] calling the next method on an iterator changes internal state that the iterator uses to keep track of where it is in the sequence. In other words, this code consumes, or uses up, the iterator

for 循环是使用迭代器的构造示例。在内存映射数据上调用 .split() 只会为该迭代器创建一个 适配器 (请注意,这并不意味着它会创建多个迭代器)。正如书中所述,适配器是使用迭代器的常见方式。

Other methods defined on the Iterator trait, known as iterator adaptors, allow you to change iterators into different kinds of iterators. You can chain multiple calls to iterator adaptors to perform complex actions in a readable way. But because all iterators are lazy, you have to call one of the consuming adaptor methods to get results from calls to iterator adaptors.

因此,该示例不会急切地在内存中创建这些拆分,并且程序只会在存在 for 循环或以其他方式使用迭代器时才做一些有价值的事情。

另请参阅: