id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	os	architecture	failure	difficulty	testcase	blockedby	blocking	related
3586	Initialisation of unboxed arrays is too slow	simonpj	simonmar	"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
}}}

"	bug	closed	high	6.12.2	libraries (other)	6.10.4	fixed			Unknown/Multiple	Unknown/Multiple	Runtime performance bug	Unknown				
