Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why using functions defined in the same module faster than the same function defined in another?

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
like image 667
claude Avatar asked Sep 13 '11 12:09

claude


People also ask

What makes it easier to reuse the same code in more than one program?

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.

What happens if you define two functions in a module that have the same name?

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.

Do functions in Python make the code run faster?

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.

How does a function differ from a module?

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.


1 Answers

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

like image 83
hammar Avatar answered Nov 16 '22 00:11

hammar