<html><body><div style="color:#000; background-color:#fff; font-family:arial, helvetica, sans-serif;font-size:12pt"><div><div>Oh, my - what an indentation :-)</div><div><br></div><div>New try:</div><div><br></div><div>----- Videresendt melding ----</div><div>Fra: Fixie Fixie &lt;fixie.fixie@rocketmail.com&gt;</div><div>Til: "haskell-cafe@haskell.org" &lt;haskell-cafe@haskell.org&gt;&nbsp;</div><div>Kopi: Clark Gaebel &lt;cgaebel@uwaterloo.ca&gt;&nbsp;</div><div>Sendt: Torsdag, 29. november 2012 20.57</div><div>Emne: Vedr: [Haskell-cafe] To my boss: The code is cool, but it is about 100 times slower than the old one...</div><div><br></div><div>Sure, the code is from the url I mentioned, both in C and in Haskell.</div><div><br></div><div>It allready seems like the haskell-version should run fast to me - it uses unboxed arrays and even unsafe functions to make it run faster. Well, have a
 look:</div><div><br></div><div>C-version:</div><div><br></div><div>#include &lt;stdint.h&gt;</div><div>#include &lt;stdio.h&gt;</div><div><br></div><div><br></div><div>#define VDIM &nbsp; &nbsp;100</div><div>#define VNUM &nbsp; &nbsp;100000</div><div><br></div><div><br></div><div><br></div><div>uint64_t prng (uint64_t w) {</div><div>&nbsp; &nbsp; w ^= w &lt;&lt; 13;</div><div>&nbsp; &nbsp; w ^= w &gt;&gt; 7;</div><div>&nbsp; &nbsp; w ^= w &lt;&lt; 17;</div><div>&nbsp; &nbsp; return w;</div><div>};</div><div><br></div><div>void kahanStep (double *s, double *c, double x) {</div><div>&nbsp; &nbsp; double y, t;</div><div>&nbsp; &nbsp; y &nbsp;= x - *c;</div><div>&nbsp; &nbsp; t &nbsp;= *s + y;</div><div>&nbsp; &nbsp; *c = (t - *s) - y;</div><div>&nbsp; &nbsp; *s = t;</div><div>}</div><div><br></div><div>void kahan(double s[], double c[]) {</div><div>&nbsp; &nbsp; for (int i = 1; i &lt;= VNUM; i++) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; uint64_t w =
 i;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (int j = 0; j</div><div>&nbsp;&lt; VDIM; j++) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kahanStep(&amp;s[j], &amp;c[j], w);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; w = prng(w);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div>};</div><div><br></div><div><br></div><div>int main (int argc, char* argv[]) {</div><div>&nbsp; &nbsp; double acc[VDIM], err[VDIM];</div><div>&nbsp; &nbsp; for (int i = 0; i &lt; VDIM; i++) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; acc[i] = err[i] = 0.0;</div><div>&nbsp; &nbsp; };</div><div>&nbsp; &nbsp; kahan(acc, err);</div><div>&nbsp; &nbsp; printf("[ ");</div><div>&nbsp; &nbsp; for (int i = 0; i &lt; VDIM; i++) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("%g ", acc[i]);</div><div>&nbsp; &nbsp; };</div><div>&nbsp; &nbsp; printf("]\n");</div><div>};</div><div><br></div><div>And the haskell
 version:</div><div><br></div><div>{-# LANGUAGE CPP, BangPatterns #-}</div><div>module Main (main) where</div><div><br></div><div>#define VDIM 100</div><div>#define VNUM 100000</div><div><br></div><div>import Data.Array.Base</div><div>import Data.Array.ST</div><div>import Data.Array.Unboxed</div><div>import Control.Monad.ST</div><div>import GHC.Word</div><div>import Control.Monad</div><div>import Data.Bits</div><div><br></div><div>prng :: Word -&gt; Word</div><div>prng w = w'</div><div>&nbsp; where</div><div>&nbsp; &nbsp; !w1 = w `xor` (w `shiftL` 13)</div><div>&nbsp; &nbsp; !w2 = w1 `xor` (w1 `shiftR` 7)</div><div>&nbsp; &nbsp; !w' = w2 `xor` (w2 `shiftL` 17)</div><div><br></div><div>type Vec s = STUArray s Int Double</div><div><br></div><div>kahan :: Vec s -&gt; Vec s -&gt; ST s ()</div><div>kahan s c = do</div><div>&nbsp; &nbsp; let inner w j</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | j &lt; VDIM &nbsp;= do</div><div>&nbsp; &nbsp; &nbsp;
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !cj &lt;- unsafeRead c j</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !sj &lt;- unsafeRead s j</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let !y = fromIntegral w - cj</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !t = sj + y</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !w' = prng w</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unsafeWrite c j ((t-sj)-y)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unsafeWrite s j t</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inner w' (j+1)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | otherwise = return ()</div><div>&nbsp; &nbsp; forM_ [1 .. VNUM] $ \i -&gt; inner (fromIntegral i) 0</div><div><br></div><div>calc :: ST s (Vec s)</div><div>calc = do</div><div>&nbsp; &nbsp; s &lt;- newArray (0,VDIM-1)
 0</div><div>&nbsp; &nbsp; c &lt;- newArray (0,VDIM-1) 0</div><div>&nbsp; &nbsp; kahan s c</div><div>&nbsp; &nbsp; return s</div><div><br></div><div>main :: IO ()</div><div>main = print . elems $ runSTUArray calc</div><div><br></div><div>Cheers,</div><div><br></div><div>Felix</div></div>  </div></body></html>