我有:
main :: IO ()
main = do
     iniciofibonaccimap <- getCPUTime
     let fibonaccimap = map fib listaVintesete
     fimfibonaccimap <- getCPUTime
     let difffibonaccimap = (fromIntegral (fimfibonaccimap - iniciofibonaccimap)) / (10^12)
     printf "Computation time fibonaccimap: %0.3f sec\n" (difffibonaccimap :: Double)
listaVintesete :: [Integer]
listaVintesete = replicate 100 27
fib :: Integer -> Integer
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)但
*Main> main
Computation time fibonaccimap: 0.000 sec我不明白为什么会发生这种情况。帮帮我-谢谢。
发布于 2010-10-20 23:25:54
哈斯克尔很懒。您在行中请求的计算
let fibonaccimap = map fib listaVintesete直到你以某种方式使用了fibonaccimap的值,它才会真正发生。因此,为了测量所用的时间,您需要引入一些强制程序执行实际计算的东西。
ETA:我最初建议打印最后一个元素来强制求值。正如TomMD指出的,这远远不够好--我强烈建议阅读他在这里的回复,以获得处理这段特定代码的实际有效方法。
发布于 2010-10-21 00:10:30
正如其他人所说,这是由于懒惰的评估造成的。要强制求值,您应该使用deepseq包和BangPatterns
{-# LANGUAGE BangPatterns #-}
import Control.DeepSeq
import Text.Printf
import System.CPUTime
main :: IO ()
main = do
 iniciofibonaccimap <- getCPUTime
 let !fibonaccimap = rnf $ map fib listaVintesete
 fimfibonaccimap <- getCPUTime
 let difffibonaccimap = (fromIntegral (fimfibonaccimap - iniciofibonaccimap)) / (10^12)
 printf "Computation time fibonaccimap: %0.3f sec\n" (difffibonaccimap :: Double)
...在上面的代码中,您应该注意三件事:
...取模)。当你发布代码提问时,请确保它运行(低,你应该包括导入)rnf deepseq的使用。这将强制对列表中的每个元素进行求值。
!fibonaccimap上的bang模式,意思是“立即执行此操作,不要等待”。这迫使列表被评估为弱头部范式(whnf,基本上只是第一个构造函数(:))。否则,rnf函数本身将保持为unevaluated.结果是:
$ ghc --make ds.hs
$ ./ds
Computation time fibonaccimap: 6.603 sec如果您打算进行基准测试,还应该使用优化(-O2)和Criterion包,而不是getCPUTime。
发布于 2010-10-20 23:25:58
我怀疑你是lazy evaluation的“受害者”。不会强制在两次计时调用之间对fibonaccimap求值,因此不会计算它。
编辑我怀疑你是在尝试对你的代码进行基准测试,在这种情况下,应该指出的是,better ways to do this更可靠。
https://stackoverflow.com/questions/3979265
复制相似问题