Consider this block of code:
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
which calculates the sum of all primes below one million. It takes 0.468 seconds to print the result on my machine. But if the definitions of isPrime
and primes
are extracted into another module, the time cost is 1.23 sec, it's almost 3x slower.
Of course I can copy/paste the difinitions everywhere it's required, but I'm also curious about why this is happening, and how to solve it.
[Edit]
I'm using GHC 7.0.3 (Windows 7 + MinGW). The code is written in EclipseFP (It uses Scion as IDE back-end), and built into an executable file with -O2
flags.
I also tried building the package outside the 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
Here's the result:
$ 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
1 — Modularity Modularization makes code easy to understand and more maintainable. It allows easy reuse of methods or functions in a program and reduces the need to write repetitively.
When you define a new function with the same name as a previously defined function, the function name is now bound to the new function object, and the old function object is reclaimed by the garbage collector.
Using built-in functions and librariesPython's built-in functions are one of the best ways to speed up your code. You must use built-in python functions whenever needed. These built-in functions are well tested and optimized.
In programming, function refers to a segment that groups code to perform a specific task. A module is a software component or part of a program that contains one or more routines. That means, functions are groups of code, and modules are groups of classes and functions.
I can reproduce this if I put isPrime
and primes
in different modules. (If they are in the same module, but still separate from main
, I see no difference).
Adding {-# INLINE isPrime #-}
gives back the same performance as having all three in one module, so it would appear that GHC needed a nudge to do cross-module inlining in this case.
This is on GHC 7.0.2, Ubuntu 11.04, 64-bit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With