[Haskell-cafe] In-place modification

Donald Bruce Stewart dons at cse.unsw.edu.au
Sun Jul 15 06:38:08 EDT 2007


hughperkins:
> 
>    Hey, guys, I just realized this test is not really fair!
>    I've been using the Microsoft .Net compiler ,which is a
>    proprietary closed-source compiler.
>    To be fair to Haskell, we should probably compare it to
>    other open source products, such as g++ and mono?
>    Here are the timings ;-)
>    Haskell
>    ======
>    J:\dev\haskell>ghc -O2 -o primechaddai.exe PrimeChaddai.hs
>    J:\dev\haskell>primechaddai
>    number of primes: 664579
>    Elapsed time: 26.234

Oh, I think we can do a bit better than that....
See below.


>    g++
>    ===
>    J:\dev\test\testperf>g++ -O2 -o prime.exe prime.cpp
>    J:\dev\test\testperf>prime
>    number of primes: 664579
>    elapsed time: 0.984
>    mono
>    ====
>    J:\dev\test\testperf>erase primecs.exe
>    J:\dev\test\testperf>gmcs primecs.cs
>    J:\dev\test\testperf>mono primecs.exe
>    number of primes: 664579
>    elapsed time: 0,719
>    Microsoft C#
>    =========
>    J:\dev\test\testperf>csc /nologo primecs.cs
>    J:\dev\test\testperf>primecs
>    number of primes: 664579
>    elapsed time: 0,6875
>    Not only does mono come close to the Microsoft .Net time,
>    both mono and Microsoft .Net are faster than g++ ;-) and
>    whack Haskell.


I reimplemented your C++ program, could you time this please?


    {-# OPTIONS -O2 -fbang-patterns #-}

    import Data.Array.IO
    import Data.Array.Base
    import System
    import Control.Monad
    import Data.Bits
    import Text.Printf

    main = sieve 10000000

    sieve n = do
        a <- newArray (2,n) True :: IO (IOUArray Int Bool) -- an array of Bool
        r <- go a n 2 0
        printf "Primes up to %8d %8d\n" (n::Int) (r::Int) :: IO ()

    go !a !m !n !c
        | n == m    = return c
        | otherwise = do
                e <- unsafeRead a n
                if e then let loop !j
                                | j < m     = do
                                    x <- unsafeRead a j
                                    when x (unsafeWrite a j False)
                                    loop (j+n)

                                | otherwise = go a m (n+1) (c+1)
                          in loop (n `shiftL` 1)
                     else go a m (n+1) c

On my machine:

    $ ghc -o primes primes.hs

    $ time ./primes
    Primes up to 10000000   664579
    ./primes  0.52s user 0.01s system 99% cpu 0.533 total

0.5s. So rather fast.

Enjoy!
  Don


More information about the Haskell-Cafe mailing list