<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>ungrasping it all: Dude, your quad-cores have been smoking way too much Haskell !</title>
    <link>http://jng.imagine27.com/articles/2007/11/29/dude-your-quad-cores-have-been-smoking-way-too-much-haskell</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>keeping the surface to see the sky</description>
    <item>
      <title>Dude, your quad-cores have been smoking way too much Haskell !</title>
      <description>&lt;p&gt;Some Haskell fans seem impressed with better performance for a fibonacci function compared with similar implementations in Ruby and Python. They should be.&lt;/p&gt;


	&lt;p&gt;Read &lt;a href="http://www.cse.unsw.edu.au/~dons/blog/2007/11/29#smoking"&gt;this&lt;/a&gt; and &lt;a href="http://www.cse.unsw.edu.au/~dons/blog/2007/11/29#smoking-4core"&gt;this&lt;/a&gt; before going on.&lt;/p&gt;


	&lt;p&gt;Impressive. Yea I thought so too until I implemented a fib function of my own in Lisp and ran it on &lt;span class="caps"&gt;SBCL&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Here it is&amp;#8230;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;(defun printfib-trec (start end)
  (format t &amp;quot;n=~D =&amp;gt; ~D~%&amp;quot; start (fib-trec start))
  (if (&amp;lt; start end)
      (printfib-trec (+ start 1) end)))

(defun fib-trec (n)
  &amp;quot;Tail-recursive Fibonacci number function&amp;quot;
  (labels ((calc-fib (n a b)
         (if (= n 0)
         a
         (calc-fib (- n 1) b (+ a b)))))
    (calc-fib n 0 1)))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

and here are comparable results for N=45. 
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;* (time (printfib-trec 0 45))

...
n=43 =&amp;gt; 433494437
n=44 =&amp;gt; 701408733
n=45 =&amp;gt; 1134903170
Evaluation took:
  0.001 seconds of real time
  8.66e-4 seconds of user run time
  4.4e-5 seconds of system run time&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;My machine is a core2 duo macbook. i.e. it&amp;#8217;s similar to a dual core machine.&lt;/p&gt;


	&lt;p&gt;Now it gets even better here are the results for N=4500&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;* (time (printfib-trec 0 4500))

...
n=4498 =&amp;gt; 4752485956810555875004869018963973043700525724009578868769474882879459154152204647915407885135917631883990751157075912405221725368578720671564885897475897464613262304334914241607212435329497497641975738086751054186028251736658640131563596639794912789288873499340565150498450487979214802149192686689502839297300024458433225040572133069627134796358948692382679582705607173927112950805086075483639678885680596072818462793625622001172877975597935926640708898109961081915885811381688288593609679366923395036172748038315089504487795839374129751161426896402825970560364499274889268094208129756388749789034972452896098894495061580172690522720566378084685514727191994472473978536748311552532810887686013014142033821544140905176979343962968937988421450684068500158256897979615387686994353406906126123537769868642652059566362453067042981495901311000274164675176218086106464588110191710522184013092019809003619950257701727043382807151105254869074540999
n=4499 =&amp;gt; 7689683809176044218107840158125230568446917722620919869236097185282672128990041547590451591499923310831823312141560648669244546575977267500013883217226532696996235625233074842634247978888031960169238969830083697466087304886911697471293091037341927771010057257419268694905456568117577378610866026860700484139627056952202998275203723635146181775748103435107099441981319375329968495793847287994466423823519958759013902933218530884486180862708252747927806488609582304095221977753080257381254319632253228943480013647285929110384030236906149951249019234788386174626368178393351733619384777746723301965464502113374050814595527544612527282323355098641401340340217066221028727128338402433420088106126843822136543545984881453537808419762831343814403375221726100769180787258588643276099557741697382968654545681825708651265429233690200167736105425793517509595122050585308615226674843578205297740460920468000168395676735878604229024852582106840990153001
n=4500 =&amp;gt; 12442169765986600093112709177089203612147443446630498738005572068162131283142246195505859476635840942715814063298636561074466271944555988171578769114702430161609497929567989084241460414217529457811214707916834751652115556623570337602856687677136840560298930756759833845403907056096792180760058713550203323436927081410636223315775856704773316572107052127489779024686926549257081446598933363478106102709200554831832365726844152885659058838306188674568515386719543386011107789134768545974863998999176623979652761685601018614871826076280279702410446131191212145186732677668241001713592907503112051754499474566270149709090589124785217805043921476726086855067409060693502705665086713985952898993812856836278577367529022358714787763725800281802824825905794600927437685238204030963093911148603509092192315550468360710831791686757243149232006736793791674270298268671415079814785035288727481753552940277003788345934437605647611832003687361710064694000
Evaluation took:
  8.698 seconds of real time
  4.731282 seconds of user run time
  0.361252 seconds of system run time&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Yes it only took under 9 seconds running in slime/emacs. Would probably be closer to 8 seconds on the command line.&lt;/p&gt;


	&lt;p&gt;As for the argument of Haskell being the easiest platform to benefit from multiple cores due to it&amp;#8217;s parallel and concurrent libraries. The evidence contradicts that. 
No changes were required to the Lisp code above to have sbcl use all cores on my system. What would be easier ?&lt;/p&gt;


	&lt;p&gt;Also the readability of the Lisp code is far simpler.&lt;/p&gt;


	&lt;p&gt;Oops. Sorry Haskell&amp;#8230;&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;BTW&lt;/span&gt; &amp;#8211; Haskell is not faster than a C implementation either(at least one that imitates Lisp) but Haskell would be far more readable beyond a trivial C implementation like this&amp;#8212;&amp;gt;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;#include &amp;lt;stdio.h&amp;gt; 

unsigned long fib_trec(unsigned long n, unsigned long a, unsigned long b) {
  if (n==0) return 0;
  if (n==1) return a;
  if (n==2) return b;
  return fib_trec(n-1, b , a+b);
}

int main() {
  int i;
  for (i=0; i &amp;lt;= 45; i++) {
    printf(&amp;quot;n=%d =&amp;gt; %d\n&amp;quot;, i, fib_trec(i, 1, 1));
  }
  return 0;
}

$ time bin/fib-c

...
n=43 =&amp;gt; 433494437
n=44 =&amp;gt; 701408733
n=45 =&amp;gt; 1134903170

real    0m0.004s
user    0m0.001s
sys    0m0.003s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt; : 
Thanks Don and the other guys for giving me a hard time for using an O(n) algorithm !&lt;/p&gt;


	&lt;p&gt;Maybe I&amp;#8217;ve accepted the following quote for too long now ;-)&lt;/p&gt;


	&lt;p&gt;&amp;#8220;The key to performance is elegance, not battalions of special cases.&amp;#8221; 
- Jon Bentley and Doug McIlroy&lt;/p&gt;</description>
      <pubDate>Thu, 29 Nov 2007 21:26:00 -0800</pubDate>
      <guid isPermaLink="false">urn:uuid:975fd91e-882b-44e7-b4db-ce1b2be70c78</guid>
      <author>ungraspiness</author>
      <link>http://jng.imagine27.com/articles/2007/11/29/dude-your-quad-cores-have-been-smoking-way-too-much-haskell</link>
      <category>Lisp</category>
      <category>Programming</category>
      <category>Haskell</category>
    </item>
  </channel>
</rss>
