使用 Criterion 对 Rust 中的随机局部搜索算法进行基准测试(分数)

问题描述 投票:0回答:1

我有一个评分函数来评估本地搜索算法,其结果因种子而异。该算法是任意的,其运行时间是固定的。尽管 Criterion 框架概括了

impl Measurement
,但我找不到一种方法让它使用分数函数来衡量。我想知道是否可以用 Criterion 来实现这个?

我无法实现

Measurement
的 API,来自 https://docs.rs/criterion/latest/criterion/measurement/trait.Measurement.html。准确地说,
start(&self)
end(&self, i)
不依赖于算法的输出。

rust benchmarking haskell-criterion
1个回答
0
投票

MarcoXerox,这是正确的。标准并不是真正为您尝试做的事情而设计的。但是,我认为使用

iter_custom
应该相当容易实现,因为它可以让您提供测量结果,而不是调用
start
end
。首先为您的分数类型定义占位符测量值。

pub struct Points;

impl Measurement for Points {
    type Intermediate = ();
    type Value = f64;

    fn start(&self) -> Self::Intermediate {
        panic!("value should be manually created")
    }

    fn end(&self, i: Self::Intermediate) -> Self::Value {
        panic!("value should be manually created")
    }

    fn add(&self, v1: &Self::Value, v2: &Self::Value) -> Self::Value {
        v1 + v2
    }

    fn zero(&self) -> Self::Value {
        0.0
    }

    fn to_f64(&self, value: &Self::Value) -> f64 {
        *value
    }

    fn formatter(&self) -> &dyn ValueFormatter {
        &PointsFormatter
    }
}

pub struct PointsFormatter;

impl ValueFormatter for PointsFormatter {
    fn scale_values(&self, _typical_value: f64, _values: &mut [f64]) -> &'static str {
        "points"
    }

    fn scale_throughputs(&self, _typical_value: f64, throughput: &Throughput, values: &mut [f64]) -> &'static str {
        let (n, units) = match throughput {
            Throughput::Bytes(x) => (*x as f64, "points/byte"),
            Throughput::BytesDecimal(x) => (*x as f64, "points/byte"),
            Throughput::Elements(x) => (*x as f64, "points/element"),
        };

        for value in values {
            *value /= n;
        }

        units
    }

    fn scale_for_machines(&self, _values: &mut [f64]) -> &'static str {
        "points"
    }
}

然后只需手动返回值作为

iter_custom
的一部分,而不是让标准执行测量。只需确保您正确考虑了所请求的迭代次数。

fn bench(c: &mut Criterion<Points>) {
    c.bench_function("foo", move |b| {
        b.iter_custom(|iters| {
            let total_score: f64 = 0.0;
            for _ in 0..iters {
                let score = black_box(foo());
                total_score += score;
            }
            total_score
        })
    });
}

我相信这应该可以解决您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.