gpt4 book ai didi

haskell - 在 Criterion 中进行基准测试之前强制评估函数输入

转载 作者:行者123 更新时间:2023-12-02 16:11:46 26 4
gpt4 key购买 nike

Criterion 中对函数进行基准测试之前,如何强制评估函数的输入?我正在尝试对某些函数进行基准测试,但希望排除评估输入 thunk 的时间。有问题的代码使用 unboxed vectors对于输入,不能对 Int 向量进行深度排序。下面的示例代码片段:

-- V is Data.Vector.Unboxed
shortv = V.fromList [1..10] :: V.Vector GHC.Int.Int16
intv = V.fromList [1..10] :: V.Vector GHC.Int.Int32

main :: IO ()
main = defaultMain [
bench "encode ShortV" $ whnf encodeInt16V shortv
,bench "encode IntV" $ whnf encodeInt32V intv
]

标准基准测试包括构建 shortv 的时间以及对上述函数进行基准测试时的intv 输入。标准测量如下 - 每个函数的测量值约为 400 纳秒,其中似乎还包括输入的构建时间:

benchmarking encode ShortV
mean: 379.6917 ns, lb 378.0229 ns, ub 382.4529 ns, ci 0.950
std dev: 10.79084 ns, lb 7.360444 ns, ub 15.89614 ns, ci 0.950

benchmarking encode IntV
mean: 392.2736 ns, lb 391.2816 ns, ub 393.4853 ns, ci 0.950
std dev: 5.565134 ns, lb 4.694539 ns, ub 6.689224 ns, ci 0.950

现在,如果基准代码的主要部分修改为以下(通过删除第二个基准函数):

main = defaultMain [
bench "encode ShortV" $ whnf encodeInt16V shortv
]

shortv 输入似乎在对encodeInt16V 函数进行基准测试之前进行评估。这确实是我想要的输出,因为这个基准测试测量函数执行的时间,不包括构建输入的时间。标准输出如下:

benchmarking encode ShortV
mean: 148.8488 ns, lb 148.4714 ns, ub 149.6279 ns, ci 0.950
std dev: 2.658834 ns, lb 1.621119 ns, ub 5.184792 ns, ci 0.950

类似地,如果我仅对“encode IntV”基准进行基准测试,我也会获得约 150 纳秒的时间。

我从 Criterion 文档中了解到,它试图避免惰性评估以获得更准确的基准测试。这是有道理的,但这里并不是真正的问题。我的问题是如何构建 Shortv 和 intv 输入,以便在传递给基准函数之前对它们进行评估。现在,我可以通过限制 defaultMain 一次仅对一个函数进行基准测试来完成此任务(如我上面所示),但这不是一个理想的解决方案。

编辑1

Criterion 基准测试还发生了其他问题,而且它似乎只发生在向量数组上,而不是列表上。如果我通过打印 Shortv 和 intv 强制进行全面评估,基准测试仍然测量时间为 ~400ns,而不是 ~150ns。代码更新如下:

main = do
V.forM_ shortv $ \x -> do print x
V.forM_ intv $ \x -> do print x
defaultMain [
bench "encode ShortV" $ whnf encodeInt16V shortv
,bench "encode IntV" $ whnf encodeInt32V intv
]

标准输出(还有 158.4% 的异常值,这似乎不正确):

estimating clock resolution...
mean is 5.121819 us (160001 iterations)
found 253488 outliers among 159999 samples (158.4%)
126544 (79.1%) low severe
126944 (79.3%) high severe
estimating cost of a clock call...
mean is 47.45021 ns (35 iterations)
found 5 outliers among 35 samples (14.3%)
2 (5.7%) high mild
3 (8.6%) high severe

benchmarking encode ShortV
mean: 382.1599 ns, lb 381.3501 ns, ub 383.0841 ns, ci 0.950
std dev: 4.409181 ns, lb 3.828800 ns, ub 5.216401 ns, ci 0.950

benchmarking encode IntV
mean: 394.0517 ns, lb 392.4718 ns, ub 396.7014 ns, ci 0.950
std dev: 10.20773 ns, lb 7.101707 ns, ub 17.53715 ns, ci 0.950

最佳答案

您可以使用evaluate在调用 defaultMain 运行基准测试之前。不确定这是否是最干净的解决方案,但它看起来像这样:

main = do
evaluate shortv
evaluate intv
defaultMain [..]

关于haskell - 在 Criterion 中进行基准测试之前强制评估函数输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8379191/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com