为什么计时器显示的如此违反直觉?

时间:2019-11-26 05:59:18

标签: performance rust

我正在解析一些文本。我需要支持unicode文本,这就是为什么我使用String::chars迭代器:

playground

use std::time::Instant;

fn main() {
    let text = "a".repeat(10000);
    let mut timer1 = 0;
    let mut timer2 = 0;

    let start1 = Instant::now();
    for pos in 1..10000 {
        let start2 = Instant::now();
        let ch = text.chars().nth(pos).unwrap();
        timer2 += start2.elapsed().as_millis();
    }
    timer1 += start1.elapsed().as_millis();

    println!("timer1: {} timer2: {}", timer1, timer2);
}

示例输出:

timer1: 4276 timer2: 133

当我认为timer2彼此之间应该非常接近时,为什么timer1.nth小呢?

P.S。我已经知道docker run --rm -v c:/Users:/data alpine ls /data 很慢,不应该使用。

1 个答案:

答案 0 :(得分:7)

您遇到解析问题。循环内部平均需要不到一毫秒的时间来执行,因此start2.elapsed().as_millis()的求值通常为0。要解决此问题,您可以在循环内部执行一些操作,而这可能需要更长的时间,或者更改分辨率从毫秒到更小的值,例如微秒或纳秒。

切换为微秒会产生更一致的时间

use std::time::{Instant};

fn main() {
    let text = "a".repeat(10000);
    let mut timer1 = 0;
    let mut timer2 = 0;

    let start1 = Instant::now();
    for pos in 1..10000 {
        let start2 = Instant::now();
        let ch = text.chars().nth(pos).unwrap();
        timer2+=start2.elapsed().as_micros();
    }
    timer1+=start1.elapsed().as_micros();

    println!("timer1: {} timer2: {}", timer1, timer2);
}

输出

timer1: 3511812 timer2: 3499669

这个问题被标记为性能,因此我想指出,使用std::Instant是一种非常繁琐的衡量性能的方法。更好的方法包括criterion.rsflamegraphcargo-bench