Time Rust中的基准测试计划

Time Rust中的基准测试计划,time,benchmarking,rust,Time,Benchmarking,Rust,如何在Rust中对程序进行基准测试?例如,如何以秒为单位获得程序的执行时间?无论实现语言如何,查找程序执行时间的一种快速方法是在命令行上运行time prog。例如: ~$ time sleep 4 real 0m4.002s user 0m0.000s sys 0m0.000s 最有趣的度量通常是user,它度量程序实际完成的工作量,而不管系统中发生了什么(sleep是一个非常无聊的程序,需要进行基准测试)real测量实际经过的时间,sys测量操作系统代表程序完成的工作

如何在Rust中对程序进行基准测试?例如,如何以秒为单位获得程序的执行时间?

无论实现语言如何,查找程序执行时间的一种快速方法是在命令行上运行
time prog
。例如:

~$ time sleep 4

real    0m4.002s
user    0m0.000s
sys     0m0.000s
最有趣的度量通常是
user
,它度量程序实际完成的工作量,而不管系统中发生了什么(
sleep
是一个非常无聊的程序,需要进行基准测试)
real
测量实际经过的时间,
sys
测量操作系统代表程序完成的工作量

这个答案已经过时了在基准测试方面,
time
板条箱与
std::time
相比没有任何优势。有关最新信息,请参见下面的答案



您可以尝试使用来计时程序中的各个组件。

目前,没有与以下任何Linux函数的接口:

  • clock\u gettime(clock\u PROCESS\u CPUTIME\u ID,&ts)
  • getrusage
  • (手册页:
    人2次
在Linux上测量Rust程序的CPU时间和热点的可用方法有:

  • /usr/bin/time程序
  • perf stat程序
  • perf record--freq 100000程序;性能报告
  • valgrind--tool=callgrind程序;kcachegrind调用grind.out.*

perf report
valgrind
的输出取决于程序中调试信息的可用性。它可能不起作用。

两年后(为了帮助任何在这一页上绊倒的未来Rust程序员),可能值得注意的是,现在有一些工具可以将Rust代码作为测试套件的一部分进行基准测试

(从下面的指南链接)使用
#[bench]
属性,可以使用标准的Rust工具在其代码中对方法进行基准测试

extern crate test;
use test::Bencher;

#[bench]
fn bench_xor_1000_ints(b: &mut Bencher) {
    b.iter(|| {
        // Use `test::black_box` to prevent compiler optimizations from disregarding
        // Unused values
        test::black_box(range(0u, 1000).fold(0, |old, new| old ^ new));
    });
}
对于命令
cargo bench
,输出如下内容:

运行1个测试
测试台\u xor\u 1000 \u ints。。。试验台:375纳秒/国际热核实验堆(+/-148)
测试结果:可以。0通过;0失败;忽略0;1测量
链接:


如果你只是想给一段代码计时,你可以使用板条箱,不过。一个后续的板条箱是

time=“*”
添加到您的
Cargo.toml

在您的主要功能和

let start = PreciseTime::now();
// whatever you want to do
let end = PreciseTime::now();
println!("{} seconds for whatever you did.", start.to(end));
完整示例 货舱 鲁斯特
extern板条箱兰德;
外置板条箱时间;
使用rand::Rng;
使用时间::PreciseTime;
fn main(){
//创建范围为0-100000000的10000000个随机整数数组
//让mut数组:[i32;10000000]=[0;10000000];
设n=10000000;
让mut array=Vec::new();
//填充数组
让mut rng=rand::thread_rng();
对于0..n中的uu{
//数组[i]=rng.gen::();
array.push(rng.gen::());
}
//分类
让我们开始=PreciseTime::now();
array.sort();
让end=PreciseTime::now();
println!(“{}秒用于对{}个整数进行排序。”,start.to(end),n);
}

要在不添加第三方依赖项的情况下测量时间,您可以使用:


我为这个()创建了一个小板条箱,它记录或打印直到范围结束的时间

#[macro_use]
extern crate measure_time;
fn main() {
    print_time!("measure function");
    do_stuff();
}
有几种方法可以对您的Rust程序进行基准测试。对于大多数真正的基准测试,您应该使用适当的基准测试框架,因为它们有助于解决一些容易出错的问题(包括统计分析)。还请阅读底部的“为什么编写基准测试很难”部分


快速简便:标准库中的
即时
持续时间
要快速检查一段代码的运行时间,可以使用中的类型。该模块相当小,但对于简单的时间测量来说很好。您应该使用而不是,因为前者是单调递增的时钟,而后者不是。示例():

使用std::time::Instant;
let before=Instant::now();
工作量();
普林顿!((.appeased()之前的运行时间:{.2?});
指定了std的
Instant
的底层平台特定实现。简言之:目前(可能永远)您可以假设它使用平台能够提供的最佳精度(或非常接近的精度)。根据我的测量和经验,这通常约为20纳秒

如果
std::time
没有为您的案例提供足够的功能,您可以查看。然而,为了测量持续时间,您不太可能需要外部板条箱


使用基准测试框架 使用框架通常是一个好主意,因为它们试图防止您犯常见错误

Rust的内置基准测试框架(仅限夜间) Rust具有方便的内置基准测试功能,不幸的是,截至2019-07年,该功能仍然不稳定。您必须将
#[bench]
属性添加到函数中,并使其接受一个
&mut test::Bencher
参数:

#![特征(测试)]
体外板条箱试验;
使用试验台;
#[法官席]
fn工作台工作量(b:&多台工作台){
b、 iter(| |工作量());
}
执行
cargo bench
将打印:

运行1个测试
测试台_工作负载。。。试验台:78534 ns/iter(+/-3606)
测试结果:可以。0通过;0失败;忽略0;1个测量值;0被过滤掉
标准 板条箱是一个稳定运行的框架,但它比内置解决方案要复杂一些。它进行更复杂的统计分析,提供更丰富的API,生成更多信息,甚至可以自动生成绘图

有关如何使用标准的更多信息,请参阅


为什么编写基准很难 编写基准测试时存在许多陷阱
[package]
name = "hello_world" # the name of the package
version = "0.0.1"    # the current version, obeying semver
authors = [ "you@example.com" ]
[[bin]]
name = "rust"
path = "rust.rs"
[dependencies]
rand = "*" # Or a specific version
time = "*"
extern crate rand;
extern crate time;

use rand::Rng;
use time::PreciseTime;

fn main() {
    // Creates an array of 10000000 random integers in the range 0 - 1000000000
    //let mut array: [i32; 10000000] = [0; 10000000];
    let n = 10000000;
    let mut array = Vec::new();

    // Fill the array
    let mut rng = rand::thread_rng();
    for _ in 0..n {
        //array[i] = rng.gen::<i32>();
        array.push(rng.gen::<i32>());
    }

    // Sort
    let start = PreciseTime::now();
    array.sort();
    let end = PreciseTime::now();

    println!("{} seconds for sorting {} integers.", start.to(end), n);
}
fn main() {
    use std::time::Instant;
    let now = Instant::now();

    {
        my_function_to_measure();
    }

    let elapsed = now.elapsed();
    println!("Elapsed: {:.2?}", elapsed);
}
#[macro_use]
extern crate measure_time;
fn main() {
    print_time!("measure function");
    do_stuff();
}