4 个版本 (2 个破坏性更新)

0.3.0 2023年6月12日
0.2.0 2022年10月7日
0.1.1 2022年7月19日
0.1.0 2022年6月16日

#78 in 性能分析

Download history 411/week @ 2024-03-13 351/week @ 2024-03-20 236/week @ 2024-03-27 257/week @ 2024-04-03 296/week @ 2024-04-10 299/week @ 2024-04-17 228/week @ 2024-04-24 180/week @ 2024-05-01 156/week @ 2024-05-08 283/week @ 2024-05-15 348/week @ 2024-05-22 278/week @ 2024-05-29 163/week @ 2024-06-05 197/week @ 2024-06-12 541/week @ 2024-06-19 285/week @ 2024-06-26

每月下载量 1,215
用于 4 crates

MIT/Apache

65KB
1.5K SLoC

🛠 小型-测试

一个小型基准测试库

Embark Embark Crates.io Docs dependency status Build status

一个受 Criterion 启发的基准测试和计时库。
这里的“受启发”意味着复制 criterion 做得好的地方(我的确是指复制),比如结果的统计分析、简化代码,并省略了大部分的自定义性。
Criterion 采用 MIT 许可,请参阅该仓库的许可或 这里

主要目标

  • 可靠的结果
  • 快速构建
  • 无依赖
  • 简单易读、理解、修改的代码

用途

有时你只需要计算某件事花费的时间。这个库旨在满足这一需求。

基准测试的目标是足够精确,以提供可靠的基准,同时占用最小空间,以便你可以轻松判断是否走错了路。

计时目标是为了提供一种方法,让你可以了解代码运行的时间,尽管它可能不如基准测试可靠。

注意事项

这个库的目标不是提供生产级的分析工具。它只是将数据打印到 stdout 以供指导。如果你需要高级分析,Criterion 提供了更适合的工具。
如果你需要找到应用程序花费时间的地方,flamegraph 可能更适合。
如果您需要在应用程序运行时追踪单个组件,那么追踪可能更适合。
最后,如果您需要更小的基准测试库,请查看benchmark-simple

未实现

有几个统计指标很受欢迎,但受到该库使用方法的限制。
由于它可能运行数十亿次迭代,因此无法在不将数据缓存到磁盘的情况下,根据看到的所有迭代计算统计信息,例如中位数、标准差和百分位数。因此,像方差或中位数这样的指标前缀为"sample",因为它们与单个迭代时间无关,而是样本之间的比较。

该库没有arg-parsing或bench-matching,因此您不能运行cargo bench . 相反,用户需要将不同的bench放入函数中,并将这些函数添加/删除到bench main中。这样做的原因是,这些库是重量级的,并且可能需要一些宏来选择要运行的bench,这会降低可读性和可理解性。

示例

了解应用程序哪些部分耗时

"我有一个迭代器,我想知道它完成需要多长时间"

use std::time::Duration;
use tiny_bench::Timeable;

pub fn main() {
    let v = (0..100)
        .map(|a| {
            my_expensive_call();
            a
        })
        .timed()
        .max();
    assert_eq!(99, v.unwrap())
    // prints:
    // anonymous [100.0 iterations in 512.25ms]:
    // elapsed	[min mean max]:	[5.06ms 5.12ms 5.20ms]
}

fn my_expensive_call() {
    std::thread::sleep(Duration::from_millis(5));
}

"我有一个有副作用的重循环,我想测量其执行时间"

use tiny_bench::run_timed_from_iterator;

fn main() {
    let generator = 0..100;
    let mut spooky_calculation = 0;
    let results = run_timed_from_iterator(generator, |i| {
        spooky_calculation += i;
    });
    results.pretty_print();
    assert_eq!(4950, spooky_calculation);
}

更复杂的比较

"我的算法相当愚蠢,但我只对最大长度为5的向量进行排序,所以在大局上可能没关系"

use tiny_bench::BenchmarkConfig;

fn main() {
    let v = vec![10, 5, 3, 8, 7, 5];
    tiny_bench::run_bench(&BenchmarkConfig::default(), || {
        let sorted = bad_sort(v.clone());
        assert_eq!(vec![3, 5, 5, 7, 8, 10], sorted);
    })
    // Prints:
    // anonymous [2.5M iterations in 4.99s with 100.0 samples]:
    // elapsed	[min mean max]:	[2.14µs 2.01µs 2.14µs]
}

fn bad_sort(mut v: Vec<u32>) -> Vec<u32> {
    let mut sorted = Vec::with_capacity(v.len());
    while !v.is_empty() {
        let mut min_val = u32::MAX;
        let mut min_index = 0;
        for i in 0..v.len() {
            if v[i] < min_val {
                min_index = i;
                min_val = v[i];
            }
        }
        sorted.push(min_val);
        v.remove(min_index);
    }
    sorted
}

"我想比较不同的实现之间的差异"

use tiny_bench::black_box;

fn main() {
    // Results are compared by label
    let label = "compare_functions";
    tiny_bench::bench_labeled(label, my_slow_function);
    tiny_bench::bench_labeled(label, my_faster_function);
    // prints:
    //compare_functions [30.3 thousand iterations in 5.24s with 100.0 samples]:
    //elapsed	[min mean max]:	[246.33µs 175.51µs 246.33µs]
    //compare_functions [60.6 thousand iterations in 5.24s with 100.0 samples]:
    //elapsed	[min mean max]:	[87.67µs 86.42µs 87.67µs]
    //change	[min mean max]:	[-49.6111% -50.7620% -64.4102%] (p = 0.00)
}

fn my_slow_function() {
    let mut num_iters = 0;
    for _ in 0..10_000 {
        num_iters += black_box(1);
    }
    assert_eq!(10_000, black_box(num_iters))
}

fn my_faster_function() {
    let mut num_iters = 0;
    for _ in 0..5_000 {
        num_iters += black_box(1);
    }
    assert_eq!(5_000, black_box(num_iters))
}

贡献

Contributor Covenant

我们欢迎社区为本项目做出贡献。

请阅读我们的贡献指南以获取有关如何开始的更多信息。在您做出任何贡献之前,请阅读我们的贡献条款

任何有意提交以包含在Embark Studios项目中的贡献,应遵守Rust标准许可模式(MIT OR Apache 2.0),因此以下列方式双许可,不附加任何额外条款或条件

许可

此贡献以下列之一双许可:

任选其一。

为了清晰起见,“您的”指的是Embark或任何其他贡献者/许可方/用户。

无运行时依赖

功能