Skip to content

Initialisation of unboxed arrays is too slow

On the Clean mailing list, Philippos Apolinarius [phi500ac@yahoo.ca] describes a small array program (using the ST monad) that runs 400x more slowly in Haskell than Clean. I can understand a bit slower (e.g. maybe they do a better job of array-bound checks), but 400x seems large. This ticket is an invitation for someone to investigate.

He writes: I wrote a very simple program to check whether Haskell improved its array processing libraries or not. Here is how to compile and run the program arr.hs in Haskell (I have used the GHC compiler):

>ghc -O arr.hs -o arr.exe

$ time arr.exe +RTS -K32000000
2.8e8

real    0m3.938s
user    0m0.031s
sys     0m0.000s

The same program in Clean:

C:\Clean 2.2\exemplos\console>arraytest.exe
280000000
Execution: 0.01  Garbage collection: 0.01  Total: 0.03

C:\Clean 2.2\exemplos\console>arraytest.exe
280000000
Execution: 0.01  Garbage collection: 0.01  Total: 0.03

This means that Clean is 390 times faster than Haskell in this particular problem. These results makes me worder whether Haskell is safer than Clean. It turns out that Haskell checks index out of range at runtime, exactly like Clean. Larger problems make the difference between Clean and Haskell even worse. For instance, neural networks like the one described in Schmidtt et al. run 400 times faster in Clean.

Below you will find the array examples. You can check that Clean is really much faster than Haskell. I wonder why the Benchmarks Game site does not report such a large difference between Haskell and Clean performances. I believe that people who wrote Haskell benchmarks for the Benchmarks Game site cheated in using foreign pointers to access arrays.

-- arr.hs
import Control.Monad.ST
import Data.Array.ST
main = print $ runST
          (do arr <- newArray (1,2000000) 
                        137.0 :: ST s 
                                  (STArray s 
                                    Int Double)
              a <- readArray arr 1
              b <- readArray arr 1
              fn 2000000 arr 0.0 )


fn i a acc | i < 1 = do (return acc) 
fn i a acc= do 
             b <- readArray a i
             writeArray a i (b+3.0)
             c <- readArray a i
             fn (i-1) a (acc+c)

Clean version

module arraytest
import StdEnv
fn i a acc | i<1 = acc
fn i a=:{[i]=b} acc
  # a= {a&[i]= b+3.0}
  # (c, a)= a![i]
  = fn (i-1) a (c+acc)
  
Start= fn 2000000 vt 0.0
where
   vt:: .{#Real}
   vt = createArray 2000001 137.0
Trac metadata
Trac field Value
Version 6.10.4
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
Edited by Simon Marlow
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information