Performance Comparison of String Splitting in Rust: Iterator vs Collection

String processing is one of the common operations. When we need to extract specific parts from a string, we can either use an iterator to process each part one by one or collect them into a collection first and then access them. Below, we will test the performance differences between these two methods.

Test Scenario

We will split the string <span>hello world, today is a nice day</span> by spaces and retrieve the first and second words, converting them to <span>String</span>.

Method 1: Iterator Approach (test_split_1)

fn test_split_1() {
    let s = "hello world, today is a nice day";
    let mut splits = s.split(" ");

    let _ = splits.next().unwrap().to_string();
    let _ = splits.next().unwrap().to_string();
}

Method 2: Collection Approach (test_split_2)

fn test_split_2() {
    let s = "hello world, today is a nice day";
    let splits = s.split(" ").collect::<vec>();

    let _ = splits[0].to_string();
    let _ = splits[1].to_string();
}</vec

Test Results

test iter 1             time:   [61.253 ns 63.274 ns 65.454 ns]
                        change: [−4.2839% +0.1741% +4.4202%] (p = 0.94 > 0.05)

test iter 2             time:   [266.26 ns 275.80 ns 285.73 ns]
                        change: [−19.624% −15.889% −11.825%] (p = 0.00 < 0.05)

The results indicate that the test_split_1 method has a significant performance advantage.

This is mainly because <span>collect</span> needs to gather all elements and create a <span>Vec</span>, which involves traversing and allocating memory for the <span>Vec</span>, both of which take time. In contrast, using an iterator employs lazy evaluation, which does not require a complete traversal and does not incur additional memory allocation.

Lazy Evaluation vs Eager Evaluation

Lazy evaluation means that an expression is only computed when needed, delaying computation until it is actually used.

Characteristics:

  • • Delayed computation: calculations are only performed when necessary
  • • Resource saving: avoids unnecessary calculations and memory allocations
  • • Stream processing: can handle infinite sequences or large datasets

For example, this is very suitable for scenarios where we only need the first few parts of a large string.

Eager evaluation means that an expression is computed immediately upon definition, regardless of whether it is used later.

Characteristics:

  • • Immediate computation: all calculations are completed at the time of definition
  • • Complete processing: all data is processed at once
  • • Memory usage: requires storage for all intermediate results

Although the performance improvement for a single call is only in the nanosecond range, in compute-intensive scenarios, it can still enhance overall performance.

Leave a Comment