[Haskell-cafe] Haskell translation and transformation

Dušan Kolář kolar at fit.vut.cz
Tue Apr 27 11:29:45 UTC 2021


Dear Café,

I've tried to make my code more compact and faster in runtime and I tried to use 
primitive types, e.g. Int#.

To omit all influences, I ended with Ackermann function:

acker :: Int# -> Int# -> Int#
acker 0# n = n +# 1#
acker m 0# = acker (m -# 1#) 1#
acker m n = acker (m -# 1#) (acker m (n -# 1#))

I was quite surprised, that the result was the same as for function without primitive 
types when it was compiled with -XStrict option. Both memory and time 
consumption was the same (small difference under 0.5%). Of course, -O2 option was 
used. :-)


I compared with the same C implementation:
int acker(int m, int n) {
    if (m==0) return n+1;
    if (n==0) return acker(m-1, 1);
    return acker(m-1, acker(m,n-1));
}

with -O2 option used for gcc, the C code is 7 times faster, for no -O options provided 
both for ghc and gcc, the C code is also 7 times faster. Thus, no difference.

My question is: does the ghc use primitive types automatically when possible? 
Otherwise, I cannot explain the same times... Or, to my big surprise, using primitives 
does not save memory and computation time, really?

And the other question is about reasoning during translation and code generation, 
what is the reason the code is so slow? I would guess that forcing primitive types 
and strict evaluation would produce a code with comparable time to C code... The 
difference seems to be like the one between compiled code to executable and to 
low level virtual machine code, which is interpreted then.

Versions I used:
ghc: 8.10.3
gcc: 10.2.0

Dušan

P.S.
I definitely don't want to make someone upset with the content, I'm simply 
wondering...
D.



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20210427/fe4b6cca/attachment.html>


More information about the Haskell-Cafe mailing list