在Haskell中编写时间函数

Jac*_*cob 27 time benchmarking haskell scala clojure

我是Haskell的新手,我希望能够计算给定函数调用或代码片段的运行时间.

在Clojure中我可以使用' 时间 ':

user=> (time (apply * (range 2 10000)))
"Elapsed time: 289.795 msecs"
2846259680917054518906413212119868890148051...
Run Code Online (Sandbox Code Playgroud)

在Scala中,我可以自己定义函数:

scala> def time[T](code : => T) =  {
     |   val t0 = System.nanoTime : Double
     |   val res = code
     |   val t1 = System.nanoTime : Double
     |   println("Elapsed time " + (t1 - t0) / 1000000.0 + " msecs")
     |   res
     | }
time: [T](=> T)T

scala> time((1 to 10000).foldLeft(1:BigInt)(_*_))
Elapsed time 274.292224 msecs
res0: BigInt = 284625968091705451...
Run Code Online (Sandbox Code Playgroud)

如何在Haskell中编写我的Scala函数或Clojure的'time'的等价物?我在Hackage上找到的System.TimeIt模块不够通用,因为它仅在测量IO计算时才有效.所以timeIt(4 + 4)不会工作,只会timeIt(print $ 4 + 4)快速烦人.此外,我真的想看看Haskell如何处理一般情况.

谢谢!

Don*_*art 22

请查看使用标准库:

只需使用标准.


关于评估深度的说明:懒惰意味着您需要决定在计时期间要进行多少评估.通常,您需要将代码缩减为普通形式.NFData类型类允许您通过rnf方法执行此操作.如果对最外层构造函数的求值是正确的,请使用seq纯代码强制进行求值.


Phi*_*ler 6

Haskell被懒惰地评估了.如果你的表达式没有一些副作用(在IO monad等中编码),那么程序不需要实际将表达式解析为值,因此不会.

要获得有意义的数字,您可以尝试计时print 4print expr采取差异,以消除字符串格式和IO的开销.


Mik*_*hat 5

懒惰意味着懒惰.时间只有在像IO这样的monad中才有意义.

时间在表达式"4 + 4"中没有意义 - 或者在任何其他数学方程中.答案就是IS.任何其他纯计算的"答案"已经在指定计算的瞬间预先确定.

不幸的是,这是你问题的"答案".事实上,在你提出问题之前就存在一个答案.它存在于1998年,当时最终定义了语言.我花了一年的时间来写这个并不重要;-)

好吧,够废话!!!! (但如果上面的内容太烦人了,那就忘了Haskell吧.)

如果Criterion包太痛苦了,只需编写测试用例并使用+ RTS进行测试.

如果你想变得非常酷,可以创建自己的monad - 一个算法执行的时间,并将结果交给算法的返回值.祝好运.我们都指望着你!