Haskell函数执行时间


74

有没有一种简单的方法可以计算Haskell中函数执行的时间?


我有关标准的问题的答案可能包含一些有用的用法示例stackoverflow.com/questions/6637968/…
gatoatigrado 2011年

3
同样,这是一种微妙的情况,因为在Haskell中不必完全“执行”功能。它们只需要足够扩展即可获得所需的任何值。考虑head [1..],它接受无限列表的第一个元素。
gatoatigrado 2011年

@gatoatigrado这就是为什么标准具有whnfnf功能的原因。
可替代

Answers:


110

最简单的事情是刚做:set +sghci,然后你可以看到你运行任何程序的执行时间,内存使用的一起。


22
但是,函数在ghci中的运行速度要慢得多。在我的测试中,速度要慢10倍左右。
2013年

3
是否可以设置所测量时间的精度(例如毫秒)?
SiXoS

1
较慢,是的,但这对于证明算法之间在时间和空间消耗上的差异似乎非常有价值。例如<pre> <code> slow_fib :: Int->整数slow_fib 0 = 0 slow_fib 1 = 1 slow_fib n = slow_fib(n-2)+ slow_fib(n-1)-与memoized_fib :: Int-> Integer memoized_fib =(映射fib [0 ..] !!)其中fib 0 = 0 fib 1 = 1 fib n = memoized_fib(n-2)+ memoized_fib(n-1)</ pre> </ code>第一个功能不仅占用更多时间,而且还占用几个数量级的空间。
亚历克斯·哈特




3

标准是最复杂的方法,尽管我发现它很难入门,而且似乎针对基准测试程序。我想计算执行时间并在程序中使用该数据,但它似乎无法解决这一需求,至少目前还不是很明显。

TimeIt非常简单,可以满足我的要求,只是它不能很好地处理纯函数。纯函数返回的时间是thunk分配时间(AFAIK),即使使用seq,也可能很难获得所需的内容。

对我有用的是基于TimeIt。

import System.TimeIt

timeItTPure :: (a -> ()) -> a -> IO (Double,a)
timeItTPure p a = timeItT $ p a `seq` return a

在timeItTPure pa中,p是负责评估纯计算结果a的函数,它可以根据需要深入地获取良好的评估时间。也许这是一个简单的模式匹配,也许它正在计算列表的长度,也许它对列表中的每个元素进行seq,也许是一个deepseq等。

seq的使用非常棘手。注意,以下功能无法正常执行。Haskell是一个神秘的事物。

badTimeItTPure a = timeItT . return $ seq (p a) a

0

https://github.com/chrissound/FuckItTimer

start' <- start
timerc start' "begin"
print "hello"
timerc start' "after printing hello"
benchmark
timerc start' "end"
end <- getVals start'
forM_ (timert end) putStrLn

输出:

"hello"
begin -> after printing hello: 0.000039555s
after printing hello -> end: 1.333936928s

对于我非常简单的用例,这似乎很好用。


嗯。。抱歉。
dfeuer
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.