<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Well, if it&#39;s &quot;in many ways the same as C&quot;, then again it&#39;s probably not</div>





idiomatic Haskell.  </blockquote><div><br></div><div>It&#39;s just a recursive equation for mandelbrot fractals.  I should have been precise, I didn&#39;t mean that the source is literally the <b><i>same</i></b> as the C source (i.e. there&#39;s no for loop, no mutable variables), rather that it presents the compiler backend with the same advantages as the C backend would have with the equivalent loop.  That is, there&#39;s no control flow obfuscation (dictionaries, calls to unknown targets), no problems with laziness, and the data representations are completely known.  </div>



<div><br></div><div><pre style="margin-top:0px;margin-bottom:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-family:&#39;Bitstream Vera Sans Mono&#39;,Courier,monospace;line-height:1.4;color:rgb(51,51,51)">

<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;background-color:rgb(255,255,204)">

<span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(153,0,0);font-weight:bold">mandel</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">::</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(68,85,136);font-weight:bold">Int</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">-&gt;</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(68,85,136);font-weight:bold">Complex</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(68,85,136);font-weight:bold">Double</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">-&gt;</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(68,85,136);font-weight:bold">Int</span></div>

<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">

<span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(153,0,0);font-weight:bold">mandel</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">max_depth</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">c</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">=</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">loop</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(0,153,153)">0</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(0,153,153)">0</span></div>

<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">

  <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">where</span>   </div>

<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">

   <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">loop</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">i</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">!</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">z</span></div>

<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">

    <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">|</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">i</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">==</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">max_depth</span>      <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">=</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">i</span></div>

<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">

    <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">|</span> magnitude <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">z</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">&gt;=</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(0,153,153)">2.0</span>  <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">=</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">i</span></div>

<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">

    <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">|</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">otherwise</span>           <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">=</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">loop</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">(</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">i</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">+</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;color:rgb(0,153,153)">1</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">)</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">(</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">z</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">*</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">z</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit;font-weight:bold">+</span> <span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">c</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;font:inherit">)</span></div>


<div><br></div></pre></div><div>It&#39;s also a loop that is readily recognized as a loop.  Now, to my knowledge, GHC doesn&#39;t explicitly recognize loops in any stage of the compiler (so as to perform loop optimizations), something which other functional compilers sometimes do.  </div>

<div><br></div><div>But, anyway, it turns out that my example above <b>is easily transformed from a bad GHC performance story into a good one</b>.  If you&#39;ll bear with me, I&#39;ll show how below.</div><div>   First, Manuel makes a good point about the LLVM backend.  My &quot;6X&quot; anecdote was from a while ago and I didn&#39;t use llvm [1].  I redid it just now with 7.4.1+LLVM, results below.  (The below table should read correctly in fixed width font, <a href="https://docs.google.com/spreadsheet/ccc?key=0AvzAHqQmHo87dHU0T0lCb1I4MFJmM2s4RnNlamJlNkE">but you can also see the data in the spreadsheet here</a>.)</div>

<div><br></div><div><div><font face="&#39;courier new&#39;, monospace">                   Time (ms)   Compiled File size   Comple+Runtime (ms)</font></div><div><font face="&#39;courier new&#39;, monospace">GHC 7.4.1 O0<span class="Apple-tab-span" style="white-space:pre">        </span>   2444<span class="Apple-tab-span" style="white-space:pre">        </span>       1241K<span class="Apple-tab-span" style="white-space:pre">        </span></font></div>

<div><font face="&#39;courier new&#39;, monospace">GHC 7.4.1 O2<span class="Apple-tab-span" style="white-space:pre">        </span>   925<span class="Apple-tab-span" style="white-space:pre">        </span>       1132K<span class="Apple-tab-span" style="white-space:pre">        </span>            1561</font></div>

<div><font face="&#39;courier new&#39;, monospace">GHC 7.4.1 O2 llvm  931         1133K</font></div><div><font face="&#39;courier new&#39;, monospace">GHC 7.0.4 O2 via-C 684         974K</font></div></div><div><br></div>
<div>
<div>So LLVM didn&#39;t help [1].  And in fact the deprecated via-C backend did the best!  Compare with GCC: </div><div><br></div><div><font face="&#39;courier new&#39;, monospace">G++ O0             300         9K                   531</font></div>

<div><font face="&#39;courier new&#39;, monospace">G++ O3             110         7K                   347</font></div><div><font face="&#39;courier new&#39;, monospace">G++ O3 recursive   116         9K<span class="Apple-tab-span" style="white-space:pre">        </span></font></div>

</div><div><br></div><div>Uh oh, the &quot;6X&quot; gap I mentioned is now closer to 9X.  And, in fact, performing a mini &quot;language shootout&quot; on the above code, reveals that GHC is doing worse than not only OCaml, but Chez Scheme, in spite of dynamic type checks, and a necessarily boxed representation of complex numbers:</div>

<div><br></div><div><div><font face="&#39;courier new&#39;, monospace">Chez Scheme 8.4    284         2.7K notStandalone   372</font></div><div><font face="&#39;courier new&#39;, monospace">OCaml              166         180K                 301</font></div>

</div><div><br></div><div>At least Python does worse!</div><div><br></div><div><span style="font-family:&#39;courier new&#39;,monospace">Python 2.6         1973</span><span class="Apple-tab-span" style="font-family:&#39;courier new&#39;,monospace;white-space:pre">        </span><span style="font-family:&#39;courier new&#39;,monospace">       NA                   </span><span style="font-family:&#39;courier new&#39;,monospace">1973</span></div>

<div><br></div><div><div><b>So here&#39;s the catch:</b>  If you check the Core and STG GHC 7.4 is actually compiling the above loop very well.  This microbenchmark turns into just a &quot;magnitude&quot; microbenchmark.  <a href="https://github.com/ghc/packages-base/blob/master/Data/Complex.hs#L115">The implementation of Data.Complex uses an EXTREMELY expensive method to avoid overflow</a> [2].</div>

<div><br></div><div>Since OCaml did well above, I took a look at <a href="http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/trunk/stdlib/complex.ml?revision=11156&amp;view=markup">their standard library&#39;s implementation, on line 51 here</a>.  They use a nice little math trick (the extra division) that is also mentioned on Wikipedia.  By implementing the <a href="https://github.com/rrnewton/MandelMicrobench/blob/97c3275ad94cbce57a688817332b42f7c32c15b4/mandel_test2.hs">same trick in Haskell, replacing the standard &quot;magnitude&quot; function</a>, we get the following results.</div>

<div><br></div><div><font face="&#39;courier new&#39;, monospace">GHC 7.4.1 </font><span style="font-family:&#39;courier new&#39;,monospace">No <br>Overflow Avoidance   </span><span style="font-family:&#39;courier new&#39;,monospace">39         </span><span style="font-family:&#39;courier new&#39;,monospace">1127K                </span><span style="font-family:&#39;courier new&#39;,monospace">674</span></div>

<div><font face="&#39;courier new&#39;, monospace">GHC 741, </font><span style="font-family:&#39;courier new&#39;,monospace">OCaml-style <br>Overflow avoidance   </span><span style="font-family:&#39;courier new&#39;,monospace">74</span>                  <span style="font-family:&#39;courier new&#39;,monospace">1127K</span><span class="Apple-tab-span" style="font-family:&#39;courier new&#39;,monospace;white-space:pre">        </span></div>

</div><div><br></div><div>Wow, now not only is the Haskell version faster than OCaml/Scheme, <b>but it is 48% faster than C++</b>, which is appropriate to the title of this email!  Of course, this probably means that C++&#39;s abs is also doing something overly expensive for overflow avoidance (or that their representation of complex numbers is not fully unpacked and stored in registers)  I haven&#39;t tracked it down yet.</div>

<div><br></div><div>But in any case, I&#39;ll be submitting a library patch.  <b>The moral, I think, is that community members could do a great deal to help &quot;Haskell&quot; performance by simply microbenchmarking and optimizing library routines in base!</b></div>

<div><br></div><div>Cheers,</div><div>  -Ryan</div><div><br></div><div>P.S. You can check out the above benchmarks from here:<a href="https://github.com/rrnewton/MandelMicrobench"> https://github.com/rrnewton/MandelMicrobench</a></div>

<div><br></div><div>[1] P.P.S. Most concerning to me about Haskell/C++ comparisons are David Peixotto&#39;s findings that LLVM optimizations are not very effective on Haskell-generated LLVM compared with typical clang-generated LLVM.</div>

<div><br></div><div>[2]  P.P.P.S. It turns out there was already a ticket (<a href="http://hackage.haskell.org/trac/ghc/ticket/2450">http://hackage.haskell.org/trac/ghc/ticket/2450</a>) regarding magnitude&#39;s performance.  But it still has bad performance even after a small refactoring was performed.</div>

<div><br></div></div>