Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

循环与迭代器的性能(Performance in Loops vs. Iterators)

要决定使用循环还是迭代器,你需要知道哪个实现更快:使用显式 for 循环的 search 函数版本还是使用迭代器的版本。

我们运行了一个基准测试,将亚瑟·柯南·道尔爵士的《福尔摩斯冒险史》的全部内容加载到一个 String 中,并在内容中查找单词 the。以下是使用 for 循环的 search 版本和使用迭代器的版本的基准测试结果:

test bench_search_for  ... bench:  19,620,300 ns/iter (+/- 915,700)
test bench_search_iter ... bench:  19,234,900 ns/iter (+/- 657,200)

这两个实现具有相似的性能!我们不会在这里解释基准测试代码,因为重点不是证明这两个版本是等价的,而是从性能角度大致了解这两个实现的比较情况。

对于更全面的基准测试,你应该使用不同大小和不同内容的文本作为 contents,使用不同的单词和不同长度的单词作为 query,以及其他各种变化。重点是:迭代器虽然是一种高级抽象,但在编译后得到的大致代码与你手写的较低级别代码相同。迭代器是 Rust 的*零成本抽象(zero-cost abstractions)*之一,这意味着使用该抽象不会带来额外的运行时开销。这类似于 C++ 的原始设计者和实现者 Bjarne Stroustrup 在他 2012 年 ETAPS 主题演讲“Foundations of C++“中定义的零开销:

通常,C++ 的实现遵循零开销原则:你未使用的内容,不需要付费。进一步说:你使用的内容,也无法手写出更好的代码。

在许多情况下,使用迭代器的 Rust 代码会编译成与你手写相同的汇编代码。诸如循环展开和消除数组访问的边界检查等优化被应用,使生成的代码极其高效。既然你知道了这一点,你可以毫无顾虑地使用迭代器和闭包了!它们使代码看起来更高级,但这样做不会带来运行时性能损失。

总结

闭包和迭代器是 Rust 中受函数式编程语言思想启发的特性。它们有助于 Rust 在低级性能下清晰地表达高级思想的能力。闭包和迭代器的实现方式使得运行时性能不受影响。这是 Rust 努力提供零成本抽象的目标的一部分。

既然我们已经改进了 I/O 项目的表达能力,让我们看看 cargo 的一些更多特性,这些特性将帮助我们与世界分享这个项目。