-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Thursday 26 June 2003 05:46 pm, Lex Stein wrote:
> Great, thanks. Those suggestions narrow the gap from GHC -O being 330x
> slower than GCC -O3 to it being 20x slower. Here are the new results:
>
> gcc -O3      0.54s
> ocamlopt     1.11s
> ghc -O      10.76s
> ocamlc      14.10s
>
> GHC is still pretty slow for native x86 instruction code. Is there any way
> to further explain the performance gap ? (new code below)

I redid both programs to make them equivalent in action. The haskell program 
was not actually summing the results, the C program was not checking array 
bounds (Haskell does), the C program did not initialize the array and the C 
program didn't print the result.

Times on my laptop (Crusoe 933):

62.061s : Haskell (Array -O2)  Note: lot's 'o disk grinding!
18.231s : Haskell (UArray -O2)
18.108s : Haskell (UArray -O2 -fvia-c)
17.443s : Haskell (UArray -O2 -funfolding-update-in-place)
 0.807s : C (-O3 without bound check)
 1.127s : C (-O3 with bound check)

At best case for Haskell, 15.5 times slower. The thing about bounds checking, 
in Haskell it's always there. In C, you might have it, you might not there is 
no certainty by the language, only by design and implementation. So with C, 
one is free to live dangerously.

I changed the "mod" value to 17, so that out of bound access takes place in 
the Haskell program. It gives me the following:
Fail: Ix{Int}.index: Index (16) out of range ((0,15))

I did the same to the C program (without the bounds checking), it spits out a 
value and give no indication that anything improper was done.


- ---------------------------------------------
Haskell Original (redone to be funtionally equivalent)
- ----------------------------------------------
import Array

a :: Array Int Int
a =  array (0,15) [(i, i) | i <- [0 .. 15] ]

acc :: Int -> Int -> Int
acc s 0  = s
acc s n  = acc (s + (a ! (n `mod` 16))) (n-1)

main :: IO ()
main = do
         print $ acc 0 100000000

- -----------------------------------------------------
C Version with some modifications as well
- ----------------------------------------------------------
#include <stdio.h>

int main ()
{
    int i;
    int k;
    int idx; 
    int a[16];

    for (i=0; i<16; ++i)
    {
      a[i] = i;
    }
    for (k=0, i=100000000; i>0; --i)
    {
       idx = i % 16;
       if((idx > 15) || (idx < 0))
       {
         fprintf(stderr, "Out of range access (0,15) value is %d\n", idx);
         exit(1);
       }
       
       k += a [idx]; 
    }

    printf("%d\n", k);
}
- --------------------------------------
New Haskell version with Unboxed Array
Note:it was a simple change of import and type
- -----------------------------------------
import Data.Array.Unboxed

a :: UArray Int Int
a =  array (0,15) [(i, i) | i <- [0 .. 15] ]

acc :: Int -> Int -> Int
acc s 0  = s
acc s n  = acc (s + (a ! (n `mod` 16))) (n-1)

main :: IO ()
main = do
         print $ acc 0 100000000
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iEYEARECAAYFAj78eqEACgkQDtpPjAQxZ6AgPQCePRrgaAmxMzfW7d2akvaXLJU7
SxAAnj7wO7vx6zXQwRVBXpMrbqw2wZDF
=oMhR
-----END PGP SIGNATURE-----

_______________________________________________
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to