Rust 에서 nightly version 에서는 benchmark 를 기본으로 제공한다. 이게 언제 stable version 에 추가 될지는 모르겠지만 rust stable 버전에서는 다음 2가지 library 가 cargo bench 명령어를 지원한다.

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

 

GitHub - bheisler/criterion.rs: Statistics-driven benchmarking library for Rust

Statistics-driven benchmarking library for Rust. Contribute to bheisler/criterion.rs development by creating an account on GitHub.

github.com

와 
https://github.com/bluss/bencher

 

GitHub - bluss/bencher: bencher is just a port of the libtest (unstable) benchmark runner to Rust stable releases. `cargo bench`

bencher is just a port of the libtest (unstable) benchmark runner to Rust stable releases. `cargo bench` on stable. "Not a better bencher!" = No feature development. Go build a better sta...

github.com

를 이용한 방법이 있다.

 

외부적으로 구현하는 방법은 매우 유사해 보인다. 

criterion.rs 는 다양한 기능을 제공하는데 비해 좀 무거워보인다. 간단히 속도 측정만을 하기에는 bencher 가 간단해 보인다. 어차피 둘다 [dev-dependencies] 에 추가하면 되기 때문에 실제 프로그램 release 시에는 해당 라이브러리를 포함하지 않는다. 

  현재 bufchr(https://github.com/yiunsr/bufchr) 이라는 rust 라이브러리를 만들고 있다. 이 라이브러리에서 benchmark 를 적용하려고 bencher 를 사용하고 있다. toml 은 다음과 같이 구성한다.

=====  https://github.com/yiunsr/bufchr/blob/0b8b02ba4a5b95b0fcdf8796e8cbcfdb18ba367a/Cargo.toml ====
[package]
name = "bufchr"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "bufchr"
path = "src/lib.rs"

[[bin]]
name = "bufchrbin"
path = "src/bin.rs"

[[bench]]
name = "bufchrbench"
harness = false
path = "benches/bench.rs"

[dev-dependencies]
bencher = "0.1.5"

==================
[[bench]] 의 path는 실제 benchmark 코드가 들어있는 위치이다. 이 코드는 각자 상황에 맞게 수정이 필요하다. 
( 디렉토리 구성은 https://github.com/yiunsr/bufchr/tree/0b8b02ba4a5b95b0fcdf8796e8cbcfdb18ba367a 을 참고하기 바란다. )

실제 benchmark 하는 코드는 아래와 같다. 
======= benches/bench.rs =======
#[macro_use]
extern crate bencher;

use bencher::Bencher;

use bufchr;

static CSV_HAYSTACK: &'static [u8] = include_bytes!("../data/gdp.csv");

fn read_gdp_csv(bench: &mut Bencher) {
    bench.iter(|| {
        let needle = b',';
        let mut bf = bufchr::Bufchr::new(CSV_HAYSTACK, needle);
        loop {
            let n = bf.next();
            if n == None{break;}
        }
    });
}

fn read_gdp_csv2(bench: &mut Bencher) {
    bench.iter(|| {
        let n1 = b',';
        let n2 = b'"';
        let mut bf = bufchr::Bufchr2::new(CSV_HAYSTACK, n1, n2);
        loop {
            let n = bf.next();
            if n == None{break;}
        }
    });
}

fn read_gdp_csv3(bench: &mut Bencher) {
    bench.iter(|| {
        let n1 = b',';
        let n2 = b'"';
        let n3 = b'\n';
        let mut bf = bufchr::Bufchr3::new(CSV_HAYSTACK, n1, n2, n3);
        loop {
            let n = bf.next();
            if n == None{break;}
        }
    });
}



benchmark_group!(benches, read_gdp_csv, read_gdp_csv2, read_gdp_csv3);
benchmark_main!(benches);
========================================

cargo bench --benches   를 통해 벤치마크를 실행할 수 있다.
실행시 아래와 같은 결과를 보여준다.
========
...................
running 3 tests
test read_gdp_csv  ... bench:       6,416 ns/iter (+/- 1,404)
test read_gdp_csv2 ... bench:      15,679 ns/iter (+/- 3,932)
test read_gdp_csv3 ... bench:      18,024 ns/iter (+/- 4,459)

test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured
=============
6,416 ns/iter  이런 것의 의미는 함수 실행시간이 6416 나노 초 => 6.416 밀리 초 => 0.00614초 동안 실행했다는 의미이다.