如何防止GHC共享?

时间:2014-02-19 20:00:08

标签: haskell optimization ghc lazy-evaluation sharing

我试图找到方法来打破haskell中顶级常量的共享,但到目前为止,它们都没有工作:

module Main where

import Debug.Trace

x1 :: Int
x1 = trace "Eval1" $ 10 + 10

x2 :: () -> Int
x2 = \() -> trace "Eval2" $ 10 + 10

x3 :: () -> Int
x3 () = trace "Eval3" $ 10 + 10

x4 :: () -> Int
x4 () = v
  where v = trace "Eval4" $ 10 + 10

x5 :: () -> Int
x5 = \() -> v
  where v = trace "Eval5" $ 10 + 10

x6 :: () -> Int
x6 () = let v = trace "Eval6" $ 10 + 10 in v

x7 :: () -> Int
x7 = let v = trace "Eval7" $ 10 + 10 in \() -> v

x8 :: () -> Int
x8 = \() -> let v = trace "Eval8" $ 10 + 10 in v


f :: Int -> Int -> Int
f y z = y + z

main :: IO ()
main = do 
  putStrLn "Start"

  print (f x1 3)
  print (f x1 4)

  print (f (x2 ()) 3)
  print (f (x2 ()) 4)

  print (f (x3 ()) 3)
  print (f (x3 ()) 4)

  print (f (x4 ()) 3)
  print (f (x4 ()) 4)

  print (f (x5 ()) 3)
  print (f (x5 ()) 4)

  print (f (x6 ()) 3)
  print (f (x6 ()) 4)

  print (f (x7 ()) 3)
  print (f (x7 ()) 4)

  print (f (x8 ()) 3)
  print (f (x8 ()) 4)

我发现当我将{-# INLINE#-} pragma放在定义上时它会破坏共享(然后它适用于所有这些)。

所以我的问题是:是否有另一种方法可以打破haskell与GHC共享顶级常量而不涉及INLINE pragma?是否保证将INLINE pragma打破共享,即使是更大的定义?如果没有,是否有保证的方式?

为什么我需要这个?例如,当我编写基准测试时,我有一个遍历的树结构。不应在基准测试运行之间共享此结构,因为构建它是基准测试的一部分。

1 个答案:

答案 0 :(得分:3)

我举了个例子以避免与-O2 -fno-full-laziness -fno-cse分享。我怀疑这一般是足够的,但请为你的特定应用做好准备。

(注意x1x5即使没有优化也会共享,因为它们的结构明确地共享计算。)