99re热视频这里只精品,久久久天堂国产精品女人,国产av一区二区三区,久久久精品成人免费看片,99久久精品免费看国产一区二区三区

基準測試

2018-08-12 22:03 更新

基準測試

Rust支持基準測試來測試用戶代碼的性能。我們來看一下 src/lib.rs 的性能如何。

`#![feature(test)]

extern crate test;

pub fn add_two(a: i32) -> i32 {
   a + 2
}

#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;

#[test]
fn it_works() {
    assert_eq!(4, add_two(2));
}

#[bench]
fn bench_add_two(b: &mut Bencher) {
    b.iter(|| add_two(2));
}
}`

注意上面代碼中的 test 的功能聲明,這表示這并不是一個穩(wěn)定的功能。

用戶需要引入 test 的封裝,來使得基準測試得以支持。通過 bench 屬性的使用,我們可以實現(xiàn)一個新的函數(shù)。與不能有參數(shù)的常規(guī)測試不同,這里的基準測試使用 &mut Bencher 來改善這個情況。這里的 Bencher 提供了一個閉包的 iter 方法。這個閉包就包含了需要進行基準測試的代碼。

用戶通過 cargo bench 指令來執(zhí)行基準測試:

$ cargo bench
   Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
 Running target/release/adder-91b3e234d4ed382a

running 2 tests
test tests::it_works ... ignored
test tests::bench_add_two ... bench: 1 ns/iter (+/- 0)

test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured

我們的非基準測試可以被忽略掉。用戶也許會注意到 cargo benchcargo test 長一個比特。這是因為 Rust 會多次執(zhí)行基準測試,然后會取一個平均值。因為在這個例子中,只是實現(xiàn)了一些簡單的功能,所以我們有一個 ns/iter (+/- 0),但是這會展示出結果的方差。

如下是編寫基準測試的建議:

  • 將安裝代碼移到 iter 循環(huán)之外,只是將用戶希望進行測試的代碼放到 iter 循環(huán)內。
  • 將實現(xiàn)同一功能的代碼放到迭代體內,不要將結果進行累計,也不要改變狀態(tài)。
  • 將外部函數(shù)進行冪等化,基準測試程序會將它測試多次。
  • 盡量使 iter 循環(huán)體內容的代碼更精簡,然后使得基準測試運行起來更快捷,使得校準器可以以更高精度的來校準。
  • 使 iter 循環(huán)體內的代碼更簡單,以幫助查明性能改進的地方(或回歸)。

疑難雜癥:優(yōu)化

在基準測試程序的編寫方面還存在一些辣手的問題:優(yōu)化編譯后的基準測試代碼可能會被優(yōu)化器篡改,這樣使得基準測試可能就不再是用戶希望的測試對象了。比如,編譯器可能會重新組織一些代碼,因為這些代碼并沒有什么作用,甚至會將它全部刪除。

#![feature(test)]

extern crate test;
use test::Bencher;

#[bench]
fn bench_xor_1000_ints(b: &mut Bencher) {
b.iter(|| {
(0..1000).fold(0, |old, new| old ^ new);
});
}

上述代碼會出現(xiàn)下述結果:

running 1 test
test bench_xor_1000_ints ... bench: 0 ns/iter (+/- 0)

test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured

為了避免上述問題,基準測試的執(zhí)行者會采用兩個方法。iter 方法可以獲得一個閉包,它可以返回一個任意值來迫使優(yōu)化器考慮這個結果,來保證優(yōu)化器不會更改基準測試代碼。下面的例子就是來展示如何校準 b.iter.

`b.iter(|| {  
// note lack of `;` (could also use an explicit `return`).
(0..1000).fold(0, |old, new| old ^ new)
});`

另一種方法是通用的 test::black_box 函數(shù),它對優(yōu)化器就是一個“黑盒”,可以迫使優(yōu)化器考慮更多的參數(shù)。

#![feature(test)]

extern crate test;

b.iter(|| {
let n = test::black_box(1000);

(0..n).fold(0, |a, b| a ^ b)
})

這些并不會讀取和更改這個值。較大的值可以直接降低開銷。

`black_box(&huge_struct)`

執(zhí)行上述任何一種變化提供了以下基準測試結果。

running 1 test
test bench_xor_1000_ints ... bench:   131 ns/iter (+/- 3)

test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured

即使使用上述方式,優(yōu)化器仍然會以不可想象的方式來修改測試用例。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號