gpt4 book ai didi

Haskell:如何使用 deepseq/force 准确地对计算进行基准测试

转载 作者:行者123 更新时间:2023-12-04 15:23:22 25 4
gpt4 key购买 nike

我有一个用 Haskell 编写的 Web 服务器,可以分多个步骤计算一些数据。

我想准确测量并显示每个操作需要多长时间。

在懒惰的情况下,有什么好的方法可以做到这一点?

请注意,“基准测试”并不是一个完全正确的术语,因为我只想测量生产系统中的时间,而不是对多次运行进行采样。我知道在这种情况下我可以使用 criterion .

最佳答案

您可以使用 force来自 Control.DeepSeq全面评估数据结构(从而要求和衡量其计算)。

一个问题是 强制使用大型数据结构本身需要一些时间!

这是因为 deepseq (由 force 使用)将遍历您的代数数据类型树,访问每个节点(但不对其进行任何操作)。

当您只对每个节点执行廉价操作时,例如 map (*2) mylist ,并尝试测量需要多长时间,这种开销可能会突然变得很大,从而扰乱您的测量。

import Control.DeepSeq
import Control.Exception (evaluate)
import Data.Time (diffUTCTime, getCurrentTime)


-- | Measures how long a computation takes, printing both the time and the
-- overhead of `force` to stdout. So it forces *twice*.
benchmarkForce :: NFData a => String -> IO a -> IO a
benchmarkForce msg action = do
before <- getCurrentTime

-- Force the first time to measure computation + forcing
result <- evaluate . force =<< action

after <- getCurrentTime

-- Force again to see how long forcing itself takes
_ <- evaluate . force $ result

afterAgain <- getCurrentTime
putStrLn $ msg ++ ": " ++ show (diffTimeMs before after) ++ " ms"
++ " (force time: " ++ show (diffTimeMs after afterAgain) ++ " ms)"
return result

where
-- Time difference `t2 - t1` in milliseconds
diffTimeMs t1 t2 = realToFrac (t2 `diffUTCTime` t1) * 1000.0 :: Double

第一个 evaluate . force运行将确保您的 action并且它的返回值被完全评估。

通过第二个 force运行结果,我们可以测量它在第一次遍历中增加了多少开销。

这当然是以两次遍历为代价的;能够测量 deepseq 的时间浪费需要你浪费那段时间两次。

这是一个用它来测量一些纯函数的例子:

main :: IO ()
main = do

l <- benchmarkForce "create list" $
return [1..10000000 :: Integer]

_ <- benchmarkForce "double each list element" $
return $ map (*2) l

_ <- benchmarkForce "map id l" $
return $ map id l

return ()

(当然它也适用于 IO 中的函数。)

输出:
create list: 1091.936 ms (force time: 71.33200000000001 ms)
double each list element: 1416.0569999999998 ms (force time: 96.808 ms)
map id l: 484.493 ms (force time: 67.232 ms)

正如我们所见, forcemap id l 中产生大约 13% 的开销案子。

关于Haskell:如何使用 deepseq/force 准确地对计算进行基准测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18612303/

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