I have a function that computes the number of divisors of an integer:
numDivisor = ( \n -> length $ filter (\x -> n `mod` x == 0) [1..n] )
When I run this function in GHCI with or without giving it a name, there is a constant ~1.4 times performance hit. Example copyable to ghci:
:set +s
x = 20000000
( \n -> length $ filter (\x -> n `mod` x == 0) [1..n] ) x
numDivisor = ( \n -> length $ filter (\x -> n `mod` x == 0) [1..n] )
numDivisor x
and the results:
Prelude> ( \n -> length $ filter (\x -> n `mod` x == 0) [1..n] ) x
72
(8.67 secs, 3,040,063,784 bytes)
Prelude> numDivisor x
72
(12.68 secs, 4,000,064,048 bytes)
It doesn't matter if x is 20000000, 200000 or is below 10000, the hit is ~1.4, also it happens when I name my function in a "where" something. In the next example I calculate the divisors for all the numbers from 1 to x, then drop them:
:set +s
x = 10000
divisorListAnon = map ( \n -> length $ filter (\x -> n `mod` x == 0) [1..n] ) [1..]
filter odd $ filter even $ take x divisorListAnon
:{
divisorListNamed = map numDivisor [1..]
where numDivisor = ( \n -> length $ filter (\x -> n `mod` x == 0) [1..n] )
:}
filter odd $ filter even $ take x divisorListNamed
the results:
Prelude> filter odd $ filter even $ take x divisorListAnon
[]
(21.17 secs, 7,613,246,464 bytes)
Prelude> filter odd $ filter even $ take x divisorListNamed
[]
(29.84 secs, 9,213,726,504 bytes)
Anyone can give some pointers what's going on? Also how can I use and name this subroutine without this performance hit? I'd prefer to give it a name, and don't use it anonymous.
Thank you,
edit:
ubuntu 20.04, ghc 8.6.5 from the ubuntu distributed ghc package, not stack