pi benchmark on ldc and dmd

bearophile bearophileHUGS at lycos.com
Tue Aug 2 16:15:17 PDT 2011


Marco Leise:

> Am 02.08.2011, 22:35 Uhr, schrieb bearophile <bearophileHUGS at lycos.com>:
> 
> > pidgits n = 0 % (0 # (1,0,1)) where
> >  i%ds
> >   | i >= n = []
> >   | True = (concat h ++ "\t:" ++ show j ++ "\n") ++ j%t
> >   where k = i+10; j = min n k
> >         (h,t) | k > n = (take (n`mod`10) ds ++ replicate (k-n) " ",[])
> >               | True = splitAt 10 ds
> >  j # s | n>a || r+n>=d = k # t
> >      | True = show q : k # (n*10,(a-(q*d))*10,d)
> >   where k = j+1; t@(n,a,d)=k&s; (q,r)=(n*3+a)`divMod`d
> >  j&(n,a,d) = (n*j,(a+n*2)*y,d*y) where y=(j*2+1)
> >
> > main = putStr.pidgits.read.head =<< getArgs
> 
> Is this Indonesian cast to ASCII? :p

I agree it's very bad looking, it isn't idiomatic Haskell code. But it contains nothing too much strange (and the algorithm is the same used in the D code). This is formatted a bit better, but I don't fully understand it yet:


import System (getArgs)

pidgits n = 0 % (0 # (1, 0, 1)) where
    i % ds
      | i >= n = []
      | True = (concat h ++ "\t:" ++ show j ++ "\n") ++ j % t
      where
        k = i + 10
        j = min n k
        (h, t) | k > n = (take (n `mod` 10) ds ++ replicate (k - n) " ", [])
               | True = splitAt 10 ds
    j # s | n > a || r + n >= d = k # t
          | True = show q : k # (n * 10, (a - (q * d)) * 10, d)
        where
            k = j + 1
            t@(n, a, d) = k & s
            (q, r) = (n * 3 + a) `divMod` d
    j & (n, a, d) = (n * j, (a + n * 2) * y, d * y)
        where
            y = (j * 2 + 1)

main = putStr . pidgits . read . head =<< getArgs


The Shootout site (where I have copied that code) ranks programs for the performance and their compactness (using a low-performance compressor...), so there you see Haskell (and other languages) programs that are sometimes too much compact and often use clever tricks to increase their performance. In normal Haskell code you don't find those tricks (this specific program seems to not use strange tricks, but on the Haskell Wiki page about this problem (http://www.haskell.org/haskellwiki/Shootout/Pidigits ) you see several programs that are both longer and slower than this one).

The first working implementation of a C program is probably long and fast enough, while the first working implementation of a Haskell program is often short but not so fast. Usually there are ways to speed up the Haskell code. My experience of Haskell is limited, so usually when I write some Haskell my head hurts a bit :-)

The higher level nature of Python allows me to implement working algorithms that are more complex, so sometimes the code ends being faster than C code, where you often avoid (at a first implementation) too much complex algorithms for fear of too much hard to find bugs, or just too much long to write implementation. Haskell in theory allows you to implement complex algorithms in a short space, and safely. In practice I think you need lot of brain to do this. Haskell sometimes looks like a puzzle language to me (maybe I just need more self-training on functional programming).

Bye,
bearophile


More information about the Digitalmars-d mailing list