Rust : 性能测试criterion库

在量化领域,对性能要求比较高,特别是高频交易,那是纳秒必争。在RUST中,测试一个函数,或一个操作耗时即性能分析,应是如何做呢?

一、计时器:systime
是否可以用std::time::systime 来计算花时情况?我们来试一试:


use std::time::SystemTime;
pub struct Stock{
    pub price:f64,
    pub volume:i32,
    pub code:String,
    pub amount:f64,
}
impl Stock{
    fn default()->Self{
        let p =10000.0_f64;
        let v =1_i32;
        Stock{
            price:p,
            volume:v,
            code:String::from("SH600036"),
            amount: p*v as f64,
        }
    }
}
fn main() {
    let now = SystemTime::now();
    let stock = Stock::default();
    let elapsed = now.elapsed().unwrap().as_nanos();
    println!("cost time :{:?} ",elapsed);

}

你会发现:
在这里插入图片描述为什么创建一个结构体要花3500纳秒,这也太不可思议了吧。其实,真实的情况并不是这样的,是因为计时器的测试误差导致。

二、计时器: Instant

use std::time::Instant;

fn main()
{
    let start = Instant::now();
    let a = Box::new(5);
    println!("cost seconds[秒] : {}", start.elapsed().as_secs());// 不需要
    println!("cost miliseconds[毫秒] : {}", start.elapsed().as_millis()); //不需要
    println!("cost microseconds[微秒] : {}", start.elapsed().as_micros());//根据需要选择
    println!("cost nanseconds[纳秒] : {}", start.elapsed().as_nanos());

}

output:

    Finished release [optimized] target(s) in 0.57s
     Running `target/release/my_bench`
cost seconds[秒] : 0
cost miliseconds[毫秒] : 0
cost microseconds[微秒] : 32
cost nanseconds[纳秒] : 39500

注意,以上只用一个就可以。否则会把打印时间包括在内,这里只是说明使用的时间精确维度。

如,

    Finished release [optimized] target(s) in 0.59s
     Running `target/release/my_bench`
cost nanseconds[纳秒] : 1400

三、专业三方库
如果要进行专业的性能测试,可以借助于专业三方性能测试库。
RUST中,专业三方库还是有不少如bencher ,criterion等。强烈推荐用criterion.rs.

https://github.com/bheisler/criterion.rs

具体大家可以到github上看看。

四、实例

1、创建测试目录
在工程中,建一个专门的测试用的目录:我这儿是在
my_bench目录下,专门创建了benches目录

在这里插入图片描述2、设置toml文件

对于my_bench工程下toml文件
在这里插入图片描述toml文件中,增加:

[dev-dependencies]
criterion = "0.3"

[[bench]]
name = "my_benchmark"
harness = false

其中,name ="my_benchmark"是有所指的,不是随便写的。这里是指,我在my_bench工程下,有一个my_benchmark.rs文件,里面有我写的性能测试代码。别的地方就不要去找了。

3、准备性能测试代码

因为toml文件中,有name =“my_benchmark” ,那么,性能测试代码就是my_benchmark.rs. 创建这个文件。
写入相应的性能测试代码:

use criterion::{black_box, criterion_group, criterion_main, Criterion};

pub struct Stock{
    pub price:f64,
    pub volume:i32,
    pub code:String,
    pub amount:f64,
}
impl Stock{
    fn default()->Self{
        let p =10000.0_f64;
        let v =1_i32;
        Stock{
            price:p,
            volume:v,
            code:String::from("SH600036"),
            amount: p*v as f64,
        }
    }
}

pub fn set_heap()->Stock{
    Stock::default()
}

pub fn box_stock() ->Box<Stock>{
    Box::new(Stock::default())
}

fn criterion_benchmark_heap(c: &mut Criterion) {
    c.bench_function("stock ", |b| b.iter(|| set_heap()));
}

fn criterion_benchmark_box(c: &mut Criterion) {
    c.bench_function("box<stock> ", |b| b.iter(|| box_stock()));
}

criterion_group!(benches, criterion_benchmark_heap,criterion_benchmark_box);
criterion_main!(benches);

4、运行cargo bench

在工程my_bench下,运行cargo bench,即可以进行性能测试代码的运行了。


    Finished bench [optimized] target(s) in 2.80s
     Running target\release\deps\my_bench-95230ab505784caf.exe

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running target\release\deps\my_benchmark-a468db13a6ba0ea3.exe
Gnuplot not found, using plotters backend
stock                   time:   [75.387 ns 83.206 ns 91.985 ns]
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild

box<stock>              time:   [168.68 ns 189.43 ns 212.00 ns]
Found 3 outliers among 100 measurements (3.00%)

从上面,我们可以得到详细的测试信息,包括运行的时间分布情况。

专业性能测试工具表明,创建一个Stock对象,大约平均需要73ns,而不是计时器显示的3500ns;
但是,创建一个Stock 的Box对象需要的时间是双倍。

五、传入参数的情况

当有参数需要传入时,可以这样:

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::BenchmarkId;
fn get_buf2(s:&String)-> *const [c_char;10]{    
    //let s = String::from("hello world!");
    let v = s.as_bytes().as_ptr() as *const [c_char;10];
    v
}
fn criterion_benchmark_buf2(c: &mut Criterion) {
    let s = &String::from("hello world!");
    c.bench_with_input(BenchmarkId::new("hello world!", &s), &s,  |b, &s| {
       b.iter(|| get_buf2(s));
    });
}
criterion_group!(benches, criterion_benchmark_buf2);
criterion_main!(benches);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值