考慮的代碼塊:爲什麼使用在同一模塊中定義的函數比在另一個模塊中定義的函數更快?
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
,其計算低於1百萬的所有質數的和。這需要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
這裏的結果:
$ 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
它的工作原理!謝謝! – claude
GHC將在模塊中執行非常積極的內聯,特別是如果內聯函數未被導出。除非您手動將它們聯機,否則它不太渴望跨模塊邊界內聯函數。 –