For a specific task, I need a lot of fast, separate entries in a mutable array. To test performance, I used the following test:
size :: Int
size = 256*256*16
arr :: UArray Int Int
arr = runST $ do
arr <- newArray (0,size) 0 :: ST s (STUArray s Int Int)
forM_ [0..size] $ \i -> do
writeArray arr i i
unsafeFreeze arr
arr_sum = foldl' (\ sum i -> sum + (arr ! i)) 0 [0..size-1]
main = print arr_sum
Here is the result:
vh:haskell apple1$ ghc -O3 bench.hs -o bench; time ./bench
Linking bench ...
549755289600
real 0m0.748s
user 0m0.697s
sys 0m0.048s
I suspected it should not take 0.7 to fill the 256 * 256 * 16 array in memory, so I tested the equivalent program in JavaScript:
size = 256*256*16;
x = new Array(size);
s = 0;
for (var i=0; i<size; ++i)
x[i] = i;
for (var i=0; i<size; ++i)
s += x[i];
console.log(s);
And the result:
vh:haskell apple1$ time node bench.js
549755289600
real 0m0.175s
user 0m0.150s
sys 0m0.024s
In C, time was 0.012s, which is a good lower bound.
#include <stdio.h>
#define SIZE (256*256*16)
double x[SIZE];
int main(){
int i;
double s = 0;
for (i = 0; i<SIZE; ++i)
x[i] = i;
for (i = 0; i<SIZE; ++i)
s += x[i];
printf("%f",s);
};
, Haskell - , . , - , , foldl' forM_, , , , . , ?