我试图想出一些方法来打破 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#-}
编译指示时,它会破坏共享(然后它适用于所有定义)。
所以我的问题是:是否有另一种方法可以打破 haskell 中与 GHC 共享顶级常量,且不涉及 INLINE
编译指示?是否保证放置 INLINE
编译指示会破坏共享,即使对于更大的定义也是如此?如果没有,有没有保证的方法?
为什么我需要这个?例如,当我编写基准测试时,我有一个被遍历的树结构。此结构不应在基准测试运行之间共享,因为构建它是基准测试的一部分。
最佳答案
我得到了您的示例,以避免与 -O2 -fno-full-laziness -fno-cse
共享。我怀疑这在一般情况下是否足够,但请针对您的特定应用程序尝试一下。
(注意,即使没有优化,x1
或 x5
也会共享,因为它们的结构显式共享计算)。
关于haskell - 如何防止GHC中的共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21891096/