56 lines
3.3 KiB
HTML
56 lines
3.3 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>Performance in Loops vs. Iterators</title>
|
||
</head>
|
||
<body>
|
||
<!-- Old headings. Do not remove or links may break. -->
|
||
<p><a id="comparing-performance-loops-vs-iterators"></a></p>
|
||
<h2 id="performance-in-loops-vs-iterators"><a class="header" href="#performance-in-loops-vs-iterators">Performance in Loops vs. Iterators</a></h2>
|
||
<p>To determine whether to use loops or iterators, you need to know which
|
||
implementation is faster: the version of the <code>search</code> function with an explicit
|
||
<code>for</code> loop or the version with iterators.</p>
|
||
<p>We ran a benchmark by loading the entire contents of <em>The Adventures of
|
||
Sherlock Holmes</em> by Sir Arthur Conan Doyle into a <code>String</code> and looking for the
|
||
word <em>the</em> in the contents. Here are the results of the benchmark on the
|
||
version of <code>search</code> using the <code>for</code> loop and the version using iterators:</p>
|
||
<pre><code class="language-text">test bench_search_for ... bench: 19,620,300 ns/iter (+/- 915,700)
|
||
test bench_search_iter ... bench: 19,234,900 ns/iter (+/- 657,200)
|
||
</code></pre>
|
||
<p>The two implementations have similar performance! We won’t explain the
|
||
benchmark code here because the point is not to prove that the two versions
|
||
are equivalent but to get a general sense of how these two implementations
|
||
compare performance-wise.</p>
|
||
<p>For a more comprehensive benchmark, you should check using various texts of
|
||
various sizes as the <code>contents</code>, different words and words of different lengths
|
||
as the <code>query</code>, and all kinds of other variations. The point is this:
|
||
Iterators, although a high-level abstraction, get compiled down to roughly the
|
||
same code as if you’d written the lower-level code yourself. Iterators are one
|
||
of Rust’s <em>zero-cost abstractions</em>, by which we mean that using the abstraction
|
||
imposes no additional runtime overhead. This is analogous to how Bjarne
|
||
Stroustrup, the original designer and implementor of C++, defines
|
||
zero-overhead in his 2012 ETAPS keynote presentation “Foundations of C++”:</p>
|
||
<blockquote>
|
||
<p>In general, C++ implementations obey the zero-overhead principle: What you
|
||
don’t use, you don’t pay for. And further: What you do use, you couldn’t hand
|
||
code any better.</p>
|
||
</blockquote>
|
||
<p>In many cases, Rust code using iterators compiles to the same assembly you’d
|
||
write by hand. Optimizations such as loop unrolling and eliminating bounds
|
||
checking on array access apply and make the resultant code extremely efficient.
|
||
Now that you know this, you can use iterators and closures without fear! They
|
||
make code seem like it’s higher level but don’t impose a runtime performance
|
||
penalty for doing so.</p>
|
||
<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
|
||
<p>Closures and iterators are Rust features inspired by functional programming
|
||
language ideas. They contribute to Rust’s capability to clearly express
|
||
high-level ideas at low-level performance. The implementations of closures and
|
||
iterators are such that runtime performance is not affected. This is part of
|
||
Rust’s goal to strive to provide zero-cost abstractions.</p>
|
||
<p>Now that we’ve improved the expressiveness of our I/O project, let’s look at
|
||
some more features of <code>cargo</code> that will help us share the project with the
|
||
world.</p>
|
||
</body>
|
||
</html>
|