{"id":591,"date":"2018-02-09T06:09:38","date_gmt":"2018-02-09T06:09:38","guid":{"rendered":"http:\/\/perfectionatic.org\/?p=591"},"modified":"2018-02-09T06:23:29","modified_gmt":"2018-02-09T06:23:29","slug":"when-julia-is-faster-than-c-digging-deeper","status":"publish","type":"post","link":"https:\/\/perfectionatic.org\/?p=591","title":{"rendered":"When Julia is faster than C, digging deeper"},"content":{"rendered":"<p>In <a href=\"http:\/\/perfectionatic.org\/?p=569\">my earlier post<\/a> I showed an example where <code>Julia<\/code> is significantly faster than <code>c<\/code>. I got this insightful response <\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\" data-dnt=\"true\">\n<p lang=\"en\" dir=\"ltr\">Random number generation is not super cheap, so you&#39;re essentially benchmarking the performance for the built-in RNG.<\/p>\n<p>&mdash; Keno Fischer (@KenoFischer) <a href=\"https:\/\/twitter.com\/KenoFischer\/status\/961732882564894722?ref_src=twsrc%5Etfw\">February 8, 2018<\/a><\/p><\/blockquote>\n<p><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<p>So I decided to dig deeper. Basically the standard <code>c<\/code> <code>rand()<\/code> is not that good. So instead I searched for the fastest <a href=\"http:\/\/www.math.sci.hiroshima-u.ac.jp\/~m-mat\/MT\/SFMT\/index.html\">Mersenne Twister<\/a> there is. I downloaded the latest code and compiled it in the fastest way for my architecture.<\/p>\n<pre lang=\"c\">\n\/* eurler2.c *\/\n#include <stdio.h>      \/* printf, NULL *\/\n#include <stdlib.h>     \/* srand, rand *\/\n#include \"SFMT.h\"       \/* fast Mersenne Twister *\/\n\nsfmt_t sfmt;\n\ndouble r2()\n{\n    return sfmt_genrand_res53(&sfmt);\n\n}\n\ndouble euler(long int n)\n{\n    long int m=0;\n    long int i;\n    for(i=0; i<n; i++){\n        double the_sum=0;\n        while(1) {\n            m++;\n            the_sum+=r2();\n            if(the_sum>1.0) break;\n        }\n    }\n    return (double)m\/(double)n;\n}\n\n\nint main ()\n{\n  sfmt_init_gen_rand(&sfmt,123456);\n  printf (\"Euler : %2.5f\\n\", euler(1000000000));\n\n  return 0;\n}\n<\/pre>\n<p>I had to compile with a whole bunch of flags which I induced from <code>SFMT<\/code>&#8216;s <code>Makefile<\/code> to get faster performance.<\/p>\n<pre lang=\"bash\">\ngcc -O3 -finline-functions -fomit-frame-pointer -DNDEBUG -fno-strict-aliasing --param max-inline-insns-single=1800  -Wall -std=c99 -msse2 -DHAVE_SSE2 -DSFMT_MEXP=1279 -ISFMT-src-1.5.1 -o eulerfast SFMT.c euler2.c \n<\/pre>\n<p>And after all that trouble we got the performance down to 18 seconds. Still slower that <code>Julia<\/code>&#8216;s 16 seconds.<\/p>\n<pre lang=\"bash\">\n$ time .\/eulerfast \nEuler : 2.71824\n\nreal    0m18.075s\nuser    0m18.085s\nsys 0m0.001s\n<\/pre>\n<p>Probably, we could do a bit better with more tweaks, and probably exceed <code>Julia<\/code>&#8216;s performance with some effort. But at that point, I got tired of pushing this further. The thing I love about <code>Julia<\/code> is how well it is engineered and hassle free. It is quite phenomenal the performance you get out of it, with so little effort. And for basic technical computing things, like random number generation, you don&#8217;t have to dig hard for a better library. The &#8220;batteries included&#8221; choices in the <code>Julia<\/code>&#8216;s standard library are pretty good.<\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\" data-dnt=\"true\">\n<p lang=\"en\" dir=\"ltr\">it is quite nice though that you can rely on the quality of Base for numerics.<\/p>\n<p>&mdash; Dr. Chris Rackauckas (@ChrisRackauckas) <a href=\"https:\/\/twitter.com\/ChrisRackauckas\/status\/961742224575774720?ref_src=twsrc%5Etfw\">February 8, 2018<\/a><\/p><\/blockquote>\n<p><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my earlier post I showed an example where Julia is significantly faster than c. I got this insightful response Random number generation is not super cheap, so you&#39;re essentially benchmarking the performance for the built-in RNG. &mdash; Keno Fischer (@KenoFischer) February 8, 2018 So I decided to dig deeper. Basically the standard c rand() [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[74,73,1],"tags":[92],"class_list":["post-591","post","type-post","status-publish","format-standard","hentry","category-julia","category-julialang","category-uncategorized","tag-julia"],"_links":{"self":[{"href":"https:\/\/perfectionatic.org\/index.php?rest_route=\/wp\/v2\/posts\/591","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/perfectionatic.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/perfectionatic.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/perfectionatic.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/perfectionatic.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=591"}],"version-history":[{"count":11,"href":"https:\/\/perfectionatic.org\/index.php?rest_route=\/wp\/v2\/posts\/591\/revisions"}],"predecessor-version":[{"id":602,"href":"https:\/\/perfectionatic.org\/index.php?rest_route=\/wp\/v2\/posts\/591\/revisions\/602"}],"wp:attachment":[{"href":"https:\/\/perfectionatic.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=591"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/perfectionatic.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=591"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/perfectionatic.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=591"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}