cla*_*ude 8 optimization haskell modularity module
考虑这段代码:
isPrime primes' n = foldr (\p r -> p * p > n || (n `rem` p /= 0 && r)) True primes'
primes = 2 : filter (isPrime primes) [3..]
main = putStrLn $ show $ sum $ takeWhile (< 1000000) primes
Run Code Online (Sandbox Code Playgroud)
它计算低于一百万的所有素数之和.在我的机器上打印结果需要0.468秒.但如果定义isPrime和primes被提取到另一个模块,时间成本是1.23秒,它几乎慢3倍.
当然,我可以在任何需要的地方复制/粘贴定义,但我也很好奇为什么会发生这种情况,以及如何解决它.
[编辑]
我正在使用GHC 7.0.3(Windows 7 + MinGW).代码是用EclipseFP编写的(它使用Scion作为IDE后端),并内置到带有-O2标志的可执行文件中.
我也尝试在IDE之外构建包:
executable test
hs-source-dirs: src
main-is: Main.hs
build-depends: base >= 4
ghc-options: -O2
other-modules: Primes
executable test2
hs-source-dirs: src2
main-is: Main.hs
build-depends: base >= 4
ghc-options: -O2
Run Code Online (Sandbox Code Playgroud)
这是结果:
$ time test/test
37550402023
real 0m1.296s
user 0m0.000s
sys 0m0.031s
$ time test2/test2
37550402023
real 0m0.520s
user 0m0.015s
sys 0m0.015s
Run Code Online (Sandbox Code Playgroud)
如果我把isPrime它primes放在不同的模块中,我可以重现这个.(如果它们在同一个模块中,但仍然分开main,我认为没有区别).
添加{-# INLINE isPrime #-}回报与将所有三个模块放在一个模块中的性能相同,因此在这种情况下,GHC似乎需要轻推进行跨模块内联.
这是在GHC 7.0.2,Ubuntu 11.04,64位