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

omqzjyyz  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(83)

我有一个score函数来评估一个局部搜索算法,该算法的结果在种子之间变化。该算法是任何时候,其运行时间是固定的。即使Criterion框架在impl Measurement上推广,我也找不到一种方法来使用score函数来测量。我想知道是否可以使用Criterion来实现这一点?
我不能从https://docs.rs/criterion/latest/criterion/measurement/trait.Measurement.html实现Measurement的API。准确地说,start(&self)end(&self, i)不依赖于算法的输出。

gcxthw6b

gcxthw6b1#

MarcoXerox,这是正确的。Criterion并不是真正为你正在尝试做的事情而设计的(我认为它可能会做出一些假设,即度量与执行时间成比例)然而,我认为使用iter_custom应该很容易实现,因为它允许您提供度量,而不是调用startend。分数类型。

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的一部分,而不是让criterion执行度量。只需确保正确考虑了所请求的迭代次数。

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
        })
    });
}


我相信这应该能解决你的问题。

相关问题