Meaningless Benchmark Redux

27 03 2011


A year ago I wrote a post called Yet Another Meaningless JavaScript Benchmark, in which I examined how different browsers behave in regards to an atypical JavaScript program (hence the meaningless part of the title). The last thing I expected was for someone to actually use this as  part of a benchmark suite.

Since I published the post both IE and Firefox have released a new major version (and Chrome has released 7 major versions, but who’s counting?) so I guess now is as good a time as any to see how the new versions fare for the same test. Just re-running the test is rather boring so I’ve added two additional sections to this post in which I experiment with some of HTML5’s features.

  1. Using the canvas tag to create a visualization of a Collatz orbit [Jump there]
  2. Use Web Worker threads in order to solve the same problem [Jump there]

I should note that I’m not a web developer, I’m just playing around with HTML5 (and blogging) so if you are a web developer some of this may seem obvious. If you’re not a web developer you probably don’t much care about HTML5 so I’m not really sure who the audience of this post is…

All the code is available to play with right here.

Rematch!

When I originally run this test with IE8 Firefox 3.5 and Chrome 3 (yes 3) I got the following results:

Re-running the same test now gives very different results. Again I’m using the latest released versions of the browsers, IE9, Firefox 4 and Chrome 10 (on the same computer).

The first thing we can see is that the playing field has been levelled, IE is no longer pulling the Y axis into the triple digits, in fact it’s planted firmly in the single digits. Chrome is unique in taking more time to perform the optimized version in more time than it did 7 versions ago (I should reiterate that this benchmark is highly specialized which means it’s not worth optimizing for and Chrome may still out perform the other browsers in real-life scenarios).

Well now we’ve got that behind us, lets look at some HTML5 features

Canvas

The canvas element gives us the opportunity to visualize what a Collatz Orbit looks like, here’s the orbit for 87:

The black dot is the starting point, odd numbers go to 3*n+1 (in red) and even numbers go to n/2 (in green), the blue dot marks where the orbit has reached 1.

The code for drawing the orbit is available here, I won’t go into it since it’s pretty trivial. All I want to add on the subject is that I calculate the whole orbit in advance so that I know how big the canvas is going to be, since it can get to be quite big a lot of the drawing may take place off screen. The orbit is drawn step by step in order to give a feeling on what’s going on (you can configure the how fast it runs).

Worker Threads

Another feature of HTML5 is Web Workers, this allows breaking out of JavaScript’s natural single threaded nature and perform calculations in separate threads. In order to prevent data races the worker threads can’t access the browser’s DOM which slightly limits their usage.

Thankfully number crunching doesn’t require access to the DOM and I had a chance to implement Collatz yet again (this is turning into a real code kata, especially counting all the different C++ implementations I wrote).

Here I launch a number of threads, each takes a sparse view of the numbers in the range. I keep track of the threads that have reported the maximal orbit for their slice and when all threads have answered I output the answer.

function parallel(limit, threads) {
    var max = [0, 0];
    var live_threads = threads;

    for (var i = 0; i < threads; ++i) {
        var worker = new Worker("euler14.js"); // Create thread object
        worker.addEventListener('message', function (e) { // This function is how the thread reports back
            var d = e.data;
            if (d.len > max[0]) {
                max = [d.len, d.num];
            }

            if (--live_threads == 0) // Done, output the result
                report("Parallel ("+ threads + ")", begin, max[1], max[0]);
        }, false);

        // Launch the thread
        worker.postMessage({ 'max': limit, 'step': threads, 'offset': i });
    }
}

The thread receives all the information it needs for the computation, when it’s done it reports its findings to the launcher (via self.postMessage) and  commits suicide.

self.addEventListener('message', function (e) {
    var limit = e.data.max;
    var add = e.data.offset;
    var step = e.data.step;
    var max = [0, 0];

    for (var i = 1; i + add < limit; i += step) {
        var length = orbit(i + add);
        if (length > max[0])
            max = [length, i + add];
    }

    self.postMessage({ 'num': max[1], 'len': max[0], 'offset': e.data.offset });
    self.close(); // Goodbye cruel wrold
}, false);

IE9 does not support Web Workers and the numbers I got when running Firefox and Chrome on this varied greatly between runs but here are the best times they achieved on my ageing dual core laptop.

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: