<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">Dear Dr. Simon.<br>I believe that I oversimplified the benchmark. However, since the suggestions improved my program a lot, I am sending you a more realistic version. Here are my comments on the link you have sent me:<br><br>1 --- The functional approach does not work for the real stuff, because I use random processes to access the array. I am sending you a more realistic program in the next email.<br><br>2 --- Although my previous example works with unboxed arrays, what I am really storing are Trees, that represent electronic circuits.<br><br>3 --- I would rather not use unsafeRead and unsafeWrite. I don't use them in Clean, and I think I should not use them in Haskell.<br><br>Here is the first program, where I replaced Double by a Tree (Windows). I will explain why I did this in a separate email, to prevent confusion. Anyway, now Haskell is 23 times slower
than Clean, as you can check from my numbers, or repeating the benchmark. BTW, I tried to use unsafeRead, and unsafeWrite, but I got a segmentation fault when I tried to run the program.<br><br>/* Clean version<br>C:\Clean 2.2\geneticprog\bench>population.exe<br>280000000<br>Execution: 0.07 Garbage collection: 0.18 Total: 0.26<br><br>C:\Clean 2.2\geneticprog\bench>population.exe<br>280000000<br>Execution: 0.07 Garbage collection: 0.17 Total: 0.25<br>*/<br>module population<br>import StdEnv<br><br>:: Op = AND | OR | NOT;<br>:: Tree= L Real | T Op [Tree];<br><br>fn i a acc | i<1 = acc<br>fn i a=:{[i]=b} acc<br> # (L n)= b<br> # a= {a&[i]= L (n+3.0)}<br> # (c, a)= a![i]<br> # (L x)= c<br> = fn (i-1) a (x+acc)<br><br>Start= fn 2000000 vt 0.0<br>where<br> vt:: .{Tree}<br> vt = createArray 2000001 (L 137.0)<br><br><br>{-# Haskell version #-}<br>{-# OPTIONS -fvia-C
-optc-O3 -fexcess-precision -optc-msse3 #-}<br><br>import Control.Monad.ST<br>import Data.Array.ST<br>import Data.Array.Base<br><br>data Op = AND | OR | NOT;<br>data Tree= L Double | T Op [Tree]<br><br>main = print $ runST<br> (do arr <- newArray (1,2000000)<br> (L 137.0) :: ST s<br> (STArray s<br> Int
Tree)<br> go arr 2000000 0.0 )<br><br>go :: STArray s Int Tree -> Int -> Double -> ST s Double<br>go !a i !acc<br> | i < 1 = return acc<br> | otherwise=do<br> b <- readArray a i<br> writeArray a i (setDouble ((getDouble b)+3.0))<br> c <- readArray a i<br> go a (i-1) (acc+ (getDouble c))<br><br>getDouble (L r)= r<br>getDouble _ = 0.0<br><br>setDouble r= L r<br><br>{-# D:\Programs\ghc-programs\bench>ghc -O2 --make \<br> bingo.hs -fvia-C -optc-O3 -optc-msse3 -o
bingo.exe<br><br>D:\ghc-programs\bench>bingo.exe +RTS -sstderr -K32000000<br>bingo.exe +RTS -sstderr -K32000000<br>2.8e8<br> 72,392,664 bytes allocated in the heap<br> 118,966,296 bytes copied during GC<br> 37,490,648 bytes maximum residency (4 sample(s))<br> 416,176 bytes maximum slop<br> 66 MB total memory in use (1 MB lost due to fragmentation)<br><br> Generation 0: 119 collections, 0 parallel, 1.42s, 1.42s elapsed<br> Generation 1: 4 collections, 0 parallel, 0.14s, 0.16s elapsed<br><br> INIT time 0.03s ( 0.00s elapsed)<br> MUT time 0.06s
( 0.06s elapsed)<br> GC time 1.56s ( 1.58s elapsed)<br> EXIT time 0.00s ( 0.02s elapsed)<br> Total time 1.66s ( 1.64s elapsed)<br><br> %GC time 94.3% (96.2% elapsed)<br><br> Alloc rate 772,188,416 bytes per MUT second<br><br> Productivity 3.8% of total user, 3.8% of total elapsed<br>#-}<br><br><br>--- On <b>Thu, 10/15/09, Simon Peyton-Jones <i><simonpj@microsoft.com></i></b> wrote:<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><br>From: Simon Peyton-Jones <simonpj@microsoft.com><br>Subject: RE: [Fwd: Re: [clean-list] Clean versus Haskell]<br>To: "Adrian Hey" <ahey@iee.org>, "clean-list@science.ru.nl" <clean-list@science.ru.nl><br>Received: Thursday, October
15, 2009, 1:22 AM<br><br><div class="plainMail">I submitted Philippos as a performance bug to GHC's trac, here:<br> <a href="http://hackage.haskell.org/trac/ghc/ticket/3586" target="_blank">http://hackage.haskell.org/trac/ghc/ticket/3586</a><br><br>If you follow the link you'll see lots of commentary, including a version that generates code twice as fast as Clean's, and is purely functional.<br><br>That said, I think it's v bad that a straightforward program runs so slowly, and it's certainly true that this is an area we could pay more attention to. (Trouble is, there are so many such areas!)<br><br>Meanwhile, I'm curious: are the arrays in Philippos's program strict? Or lazy? If strict, that's a pretty big difference. (The "STU" arrays mentioned in the above link are strict and unboxed; that's what the "U" means.)<br><br>Simon<br><br>| -----Original Message-----<br>| From: <a
ymailto="mailto:clean-list-bounces@science.ru.nl" href="/mc/compose?to=clean-list-bounces@science.ru.nl">clean-list-bounces@science.ru.nl</a> [mailto:<a ymailto="mailto:clean-list-bounces@science.ru.nl" href="/mc/compose?to=clean-list-bounces@science.ru.nl">clean-list-bounces@science.ru.nl</a>] On<br>| Behalf Of Adrian Hey<br>| Sent: 15 October 2009 07:33<br>| To: <a ymailto="mailto:clean-list@science.ru.nl" href="/mc/compose?to=clean-list@science.ru.nl">clean-list@science.ru.nl</a><br>| Subject: [Fwd: Re: [clean-list] Clean versus Haskell]<br>| <br>| <br>| -------- Original Message --------<br>| Subject: Re: [clean-list] Clean versus Haskell<br>| Date: Thu, 15 Oct 2009 06:41:20 +0100<br>| From: Adrian Hey <<a ymailto="mailto:ahey@iee.org" href="/mc/compose?to=ahey@iee.org">ahey@iee.org</a>><br>| To: Philippos Apolinarius <<a ymailto="mailto:phi500ac@yahoo.ca" href="/mc/compose?to=phi500ac@yahoo.ca">phi500ac@yahoo.ca</a>><br>| References:
<<a ymailto="mailto:8400.82204.qm@web58803.mail.re1.yahoo.com" href="/mc/compose?to=8400.82204.qm@web58803.mail.re1.yahoo.com">8400.82204.qm@web58803.mail.re1.yahoo.com</a>><br>| <br>| Hello Philippos,<br>| <br>| GHC has a long standing performance bug for garbage collection and<br>| mutable arrays:<br>| <br>| <a href="http://hackage.haskell.org/trac/ghc/ticket/650" target="_blank">http://hackage.haskell.org/trac/ghc/ticket/650</a><br>| <br>| For some reason they haven't (can't?) fixed it. I guess the<br>| authors of Haskell/ghc shootout entries are aware of this so don't<br>| use native mutable arrays in their entries (at least not those that<br>| show haskell/ghc to be "fast" :-)<br>| <br>| Regards<br>| --<br>| Adrian Hey<br>| <br>| Philippos Apolinarius wrote:<br>| > I wrote a very simple program to check whether Haskell improved its array<br>| processing libraries or not. Here is how to compile and run the program arr.hs in<br>| Haskell (I
have used the GHC compiler):<br>| ><br>| >> ghc -O arr.hs -o arr.exe<br>| ><br>| > $ time arr.exe +RTS -K32000000<br>| > 2.8e8<br>| ><br>| > real 0m3.938s<br>| > user 0m0.031s<br>| > sys 0m0.000s<br>| ><br>| > The same program in Clean:<br>| > C:\Clean 2.2\exemplos\console>arraytest.exe<br>| > 280000000<br>| > Execution: 0.01 Garbage collection: 0.01 Total: 0.03<br>| ><br>| > C:\Clean 2.2\exemplos\console>arraytest.exe<br>| > 280000000<br>| > Execution: 0.01 Garbage collection: 0.01 Total: 0.03<br>| ><br>| > This means that Clean is 390 times faster than Haskell in this particular problem.<br>| These results makes me worder whether Haskell is safer than Clean. It turns out that<br>| Haskell checks index out of range at runtime, exactly like Clean. Larger problems<br>| make the difference between Clean and Haskell
even worse. For instance, neural<br>| networks like the one described in Schmidtt et al. run 400 times faster in Clean.<br>| ><br>| > Haskell seems to be slow, and not safe. For instance, GHC compiler does not at a<br>| program trying to write into a closed handle.<br>| ><br>| > module Main where<br>| > import System( getArgs )<br>| > import IO<br>| ><br>| > main = do<br>| > args <- getArgs<br>| > if (length args /= 2)<br>| > then putStr "Usage: f1a f2a <n>"<br>| > else (do<br>| > fromHandle <- openFile (head args) ReadMode<br>| > contents <- hGetContents
fromHandle<br>| > toHandle <- openFile (head (tail args)) WriteMode<br>| > hClose toHandle -- Comment this line<br>| > hPutStr toHandle contents<br>| > hClose toHandle<br>| > putStr "Done.")<br>| ><br>| > The Clean equivalent program is somewhat smaller. In my opinion it is easier to<br>| understand. What is more important, Clean compiler balks at closed handles.<br>| ><br>| > module cleancopy<br>| > import StdEnv, ArgEnv<br>| ><br>| > Start w<br>| > # argv= getCommandLine<br>| > | size argv < 3 = abort "Usage, etc."<br>| > # (ok, f, w)= fopen argv.[1]
FReadText w<br>| > (contents, f)= freads f 64000<br>| > (ok, f, w)= fopen argv.[2] FWriteText w<br>| > f= fwrites contents f<br>| > = fclose f w<br>| ><br>| > Below you will find the array examples. You can check that Clean is really much<br>| faster than Haskell. I wonder why the Benchmarks Game site does not report such a<br>| large difference between Haskell and Clean performances. I believe that people who<br>| wrote Haskell benchmarks for the Benchmarks Game site cheated in using foreign<br>| pointers to access arrays.<br>| ><br>| > -- arr.hs<br>| > import Control.Monad.ST<br>| > import Data.Array.ST<br>| > main = print $ runST<br>| > (do arr <- newArray (1,2000000)<br>| >
137.0 :: ST s<br>| > (STArray s<br>| > Int Double)<br>| > a <- readArray arr 1<br>| > b <- readArray arr 1<br>| > fn 2000000 arr 0.0 )<br>| ><br>| ><br>| > fn i a acc | i < 1 = do (return acc)<br>| > fn i a acc= do<br>| > b <- readArray a i<br>| > writeArray a i (b+3.0)<br>| > c <- readArray a i<br>| >
fn (i-1) a (acc+c)<br>| ><br>| > //Clean version<br>| > module arraytest<br>| > import StdEnv<br>| > fn i a acc | i<1 = acc<br>| > fn i a=:{[i]=b} acc<br>| > # a= {a&[i]= b+3.0}<br>| > # (c, a)= a![i]<br>| > = fn (i-1) a (c+acc)<br>| ><br>| > Start= fn 2000000 vt 0.0<br>| > where<br>| > vt:: .{#Real}<br>| > vt = createArray 2000001 137.0<br><br>_______________________________________________<br>clean-list mailing list<br><a ymailto="mailto:clean-list@science.ru.nl" href="/mc/compose?to=clean-list@science.ru.nl">clean-list@science.ru.nl</a><br><a href="http://mailman.science.ru.nl/mailman/listinfo/clean-list" target="_blank">http://mailman.science.ru.nl/mailman/listinfo/clean-list</a><br></div></blockquote></td></tr></table><br>
<p class="MsoNormal"> </p>
<tbody><tr>
<td style="padding: 0.75pt;">
<div class="MsoNormal" style="text-align: center;" align="center"><font face="Times New Roman" size="3"><span style="font-size: 12pt;">
<hr align="center" size="1" width="100%">
</span></font></div>
<p class="MsoNormal"><font face="Times New Roman" size="3"><span style="font-size: 12pt;"><img id="_x0000_i1026" src="http://us.i1.yimg.com/us.yimg.com/i/ca/iotg_search.jpg" align="absbottom" border="0" height="25" hspace="4" width="25"><a href="http://ca.toolbar.yahoo.com/" target="_new"><b><span style="font-weight: bold;" lang="NO-BOK">Yahoo!
Canada Toolbar :</span></b><span lang="NO-BOK"> Search from anywhere on
the web and bookmark your favourite sites. Download it now! </span></a>
</span></font><span lang="NO-BOK"><o:p></o:p></span></p>