haskell - 如何防止GHC中的共享?

标签 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#-} 编译指示时,它会破坏共享(然后它适用于所有定义)。

所以我的问题是:是否有另一种方法可以打破 haskell 中与 GHC 共享顶级常量,且不涉及 INLINE 编译指示?是否保证放置 INLINE 编译指示会破坏共享,即使对于更大的定义也是如此?如果没有,有没有保证的方法?

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

最佳答案

我得到了您的示例,以避免与 -O2 -fno-full-laziness -fno-cse 共享。我怀疑这在一般情况下是否足够,但请针对您的特定应用程序尝试一下。

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

关于haskell - 如何防止GHC中的共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21891096/

相关文章:

haskell - 指定嵌套类型变量约束在 Haskell 中属于同一实例

javascript - Fay、渲染循环和鼠标事件

haskell - Haskell 中的镜头与 Clojure 中使用按键序列之间有哪些异同?

haskell - 你能在 Haskell 中进行类型级别的模式匹配吗?

c++ - 间接运算符的 C++ 标准描述是否保证不会优化内存写入?

c++ - 按值显式复制构造函数或隐式参数

c++ - 数组变量中有更多变量还是多一维?

haskell - 约束子集高阶约束

haskell - 为什么 GHC Haskell 中没有存在量化的类型变量

windows - 如何更改ghc的路径?