Number crunching with javascript - a tutorial

Christian Harms's picture

Use Webworker

Webworker is a new HTML5 feature supported by modern browsers since mozilla firefox 3.1, apple webkit or google chrome. It does not work on opera, firefox 3.0 or konqueror. The worker is a JavaScript object in a extra thread who can communicate with the main application via the function postMessage.

For the simple example I created a a "worker hook function" in my numbers.js file and started the cruncher object synchronous like in the normal version. The final version can split the number range in parts for each worker thread.

  1.    worker = new Worker("numbers.js");
  2.    worker.onmessage = function(resultStr) { window.alert(resultStr); }
  3.    worker.postMessage("3,1,15000");

The Worker object is loaded, will start in background the calculation and give the result as json-string to the callback function (which shows as ugly alert box).

  1. //this will load the local json2-file from crockford, got from http://json.org/
  2. importScripts("json2.js");
  3. //this is the called function from worker.postMessage
  4. //@param {String} "variant,from,to"
  5. onmessage = function(params) {
  6.     var p = params.data.split(",");
  7.     var worker = new com.unitedCoders['Numbers'+p[0]]();
  8.     var results = worker.findSociable(+p[1], +p[2]);
  9.     //this is the calling function for worker.onmessage
  10.     postMessage(JSON.stringify(results));
  11. };

I expect better results with using more than one worker. Best would be one worker per cpu core. Chrome scales perfectly because the browser has an extra worker process for every tab! Firefox has one process but I can see more the one working thread in top.

Get modern browser running in ubuntu

If you using ubuntu (or other apt-based linux) and don't have the newest firefox (or didn't upgrad to ubuntu 10.x), here is the command to get it directly. Firefox can be installed via

  1.  > sudo apt-get install firefox-3.5
.

Because googles browser chrome is calling home, use the privacy cleaned version Iron chrome from SRWare (see Review here and here).

Or get the normal version via apt-get following the steps from ubuntugeek.com.

The other two big player apple safari and internet explorer won't run natively under ubuntu. I will try to install safari with wine hoping the core JavaScript speed doesn't differ. And for the internet explorer there is the fine ie4linux project.

Benchmarking the variants

How to benchmark the code? I created the three evolutionary code versions and three work modes. First the directly variant as normal JavaScript function, second run the same function in a Webworker in a thread. The third version will split the calculation in 4 parts and start 4 webworker to hit the score.

For testing the variants in different browser I choosed on my ubuntu eeeBox the following browser, because all candidates use different javascript engines:

Browsername & Javascript Engine direct mode webworker mode
first version cached version single function first version cached version single function
Iron chrome 3.x (from SRWare.net with V8) 1882 623 190 1937 640 559
Firefox 3.5 with Tracemoney 5122 1861 550 6011 1865 1735
Opera 10 with Futhark 12656 3195 1050 not available
Konqueror mit KJS 12115 3011 1349 not available

results

My optimization in three variants works on every browser and result caching is OK. V8 will optimize my single function variant dramatically - the run-time JavaScript optimizer works great! The starting and communication overhead for the worker is reasonable and it can benefits while computing more the one second per thread.

The four thread worker version was not faster than the normal version? OK, with only one core on one cpu (my intel Atom) could threaded number crunching not scale! Testing on a four core CPU: Yes it works fine but not linear, try it out in the interactive demo (open the firebug console for logging info)!

But don't forget your old-stuffed visitors (or internet explorer users): If your JavaScript calculations runs in chrome fine - your visitors with older browser will be frustrated! Factor 10 in calculation time is possible.

live demo

direct mode Worker mode 4-Worker mode
Here the results will be printed.

the end

Hoping this detailed tutorial in building a number cruncher in javascript helps to understand the inheritance of prototype classes, optimization steps and benchmarking javascript code.

Trackback URL for this post:

http://www.united-coders.com/trackback/47

Fave added

Your story was featured in CodeFave Here is the link to vote it up and promote it: http://www.codefave.com