如何确定何时计算表达式?

时间:2011-03-17 18:58:53

标签: performance haskell lazy-evaluation

我最近一直在学习haskell,而且我理解懒惰评估的概念。我发现的一件事是,通常很难推断出何时会对表达式进行评估。

有没有一种好方法可以获得有关评估方面正在发生的事情的信息?理想情况下,我希望看到类似于堆栈跟踪或依赖关系列表的内容,以显示何时需要评估表达式,以及必须评估其依赖的其他表达式。

3 个答案:

答案 0 :(得分:4)

另一种可能性是使用Debug.Trace设施。

答案 1 :(得分:3)

请参阅此处查看GHCi debugger会话的示例。

答案 2 :(得分:0)

如果在其余代码中需要其值,则实际上会评估表达式。在某些情况下,您可以拥有一个程序,该程序无法访问数据结构的任何元素,因为在您的程序中您没有使用它们:

import System.Environment    

-- this first version of the foo function evaluate a list (reversing) but don't use it any more
-- the result show that nothing is compute even the reverse du to the haskell lazyness
foo :: [a] -> IO ()
foo [] = print ("empty list")
foo xs = do let xs' = reverse xs in print ("reversable list")

-- this function evaluate the reversed list's length, so the compiler is oblige here to evaluate
-- both reverse and length
foo' :: [a] -> IO ()
foo' [] = print ("empty list")
foo' xs = do let xs' = reverse xs in print ("reversable list of size " ++ show (length xs'))    

main = do 
    [arg1, arg2] <- getArgs
    let listSize = read arg1
    let prog     = read arg2 
    if prog == 0 then foo (replicate listSize 'e') else foo' (replicate listSize 'e')  

执行结果显示以下时间执行

./stack1 100000000 0  -- calling the foo function with 100000000 elements
"reversable list"

real    0m0.003s
user    0m0.004s
sys  0m0.000s

time ./stack1 0 0 -- calling the foo function with an empty list
"empty list"

real    0m0.003s
user    0m0.004s
sys  0m0.004s

我们观察到我们有相同的执行时间。让我们试试 foo'

time ./stack1 0 1 -- calling foo' with an empty list
"empty list"

real    0m0.003s
user    0m0.004s
sys  0m0.000s

time ./stack1 100000000 2
"reversable list of size 100000000"

real    0m8.662s -- here 8 minutes are spend to reverse and get the list length
user    0m7.944s
sys  0m0.716s