我对 Haskell 比较陌生,我正在尝试学习如何使用 do 表示法按顺序执行不同的操作。
特别是,我正在编写一个程序来对算法(一个函数)进行基准测试
foo :: [String] -> [String]
为此,我想编写一个类似的函数
import System.CPUTime
benchmark :: [String] -> IO Integer
benchmark inputList = do
start <- getCPUTime
let r = foo inputList
end <- getCPUTime
return (end - start) -- Possible conversion needed.
最后一行可能需要转换(例如到毫秒),但这不是这个问题的主题。
这是测量在某些参数 inputList 上计算函数 foo 所需时间的正确方法吗?
换句话说,表达式
foo inputList
在行动前完全减少end <- getCPUTime
被执行?或将r
只绑定(bind)到 thunk foo inputList
?更一般地说,如何确保在执行某些操作之前完全评估表达式?
几个月前,程序员曾问过这个问题(见 here),并在那里得到了一个公认的答案,但由于它属于堆栈溢出,因此它已被关闭为题外话。该问题无法移至堆栈溢出,因为它已超过 60 天。因此,与版主一致,我在这里重新发布问题并自己发布已接受的问题,因为我认为它包含一些有用的信息。
最佳答案
最初由用户 ysdx 给出的答案on programmers :
Indeed you version will not benchmark your algorithm. As
r
is not used it will not be evaluated at all.You should be able to do it with DeepSeq:
benchmark :: [String] -> IO Integer benchmark inputList = do start <- getCPUTime let r = foo inputList end <- r `deepseq` getCPUTime return (end - start)
(
a `deepseq` b
) is some "magic" expression which forces the complete/recursive evaluation ofa
before returningb
.
关于haskell - 如何在 Haskell 中强制评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14163072/