Hello!
I was playing with monadic looping a'la replicateM_ and I created this
function:
for :: Int -> IO () -> IO ()
for 0 _ = return ()
for n x = x >> for (n - 1) x
Compiled with -O2, it is really fast and makes no unnecessary
allocations. Tested with this main
main = for 10000000 (return ())
it gives the following stats
<>
Cool!
( this is still 10 times slower than g++ -O3, but a similar pure function
is only 3 times slower, and I am satisfied with such results (at this
moment ;) )
Unfortunately, the program I was playing with could call 'for' with
negative n, for which it was supposed to make 0 iterations, and this
version definitely makes too many iterations.
So I made another version:
for :: Int -> IO () -> IO ()
for n x | n > 0 = x >> for (n - 1) x
| otherwise = return ()
To my surprise, it was much slower and made many allocations:
<>
I checked in -ddump-simpl that Ints are getting unboxed in both
versions.
Then I noticed the cause:
GHC.Prim.<# returns a boxed, heap allocated Bool, and so do other
primitive comparison operators.
Would it be difficult to add Bool unboxing to GHC?
Maybe it would suffice to use preallocated False and True?
Best regards,
Tom
--
.signature: Too many levels of symbolic links