the birth of a faster monkey

Over the past year, JavaScript performance on the web has undergone a striking revolution. Virtually every browser has improved its engine to produce significant gains in execution speed; Firefox is about 3 times faster than Firefox 2 in various JavaScript benchmarks, for example. But of course, developer and user demand for performance is insatiable, and at Mozilla we demand it ourselves, since our application itself is largely and increasingly written in JavaScript. In addition to improving the performance of web applications, our work on JS performance in Firefox 3 made our own application snappier and more responsive.

We’re not done. In addition to continuing to work on our existing JavaScript interpreter (some 20% improved over Firefox 3 already), we’re also looking farther into the future of JS performance, and have some early news to share. Permit me, if you will, to set the stage:

Core primitives improved by 20-40x

These are the early results from a project we’ve been calling TraceMonkey, which adds native code compilation to Mozilla’s JavaScript engine (“SpiderMonkey”). Based on a technique developed at UC Irvine called “trace trees“, and building on code and ideas shared with the Tamarin Tracing project, a few of us have spent the last 2 months (and most of the last few nights) teaching SpiderMonkey some exciting new tricks.

The goal of the TraceMonkey project — which is still in its early stages — is to take JavaScript performance to another level, where instead of competing against other interpreters, we start to compete against native code. Even with this very, very early version we’re already seeing some promising results: a simple “for loop” is getting close to unoptimized gcc:

for loop: gcc 1070ms, js 910ms

Yesterday we landed TraceMonkey in the Firefox 3.1 development tree, configured off by default. We have bugs to fix, and an enormous number of optimizations still to choose from, but we’re charging full speed ahead on the work we need to do for this to be a part of Firefox 3.1. Depending on the benchmarks you choose, you might see massive speed-up, minor speed-up, or maybe even some slowdown — those latter cases are definitely bugs, and reporting them through bugzilla will be a big help.

Here are the current speedups of some common and uncommon benchmarks, as compared to Firefox 3: Apple’s SunSpider, the SunSpider “ubench” tests added for squirrelfish; an image manipulation demo; and a test of the Sylvester 3D JavaScript library doing matrix multiplication.

4 bench graph: sunspider at 1.8x, ubench at 22.4x, image manipulation at 6.5x, sylvester at 6.2x

There are many wins left in each one of those benchmarks, and we’ll be working on those through Firefox 3.1 and beyond: better code generation, more efficient guards, improvements to some data structures, parallel compilation, use of specific processor features, new optimization passes, tracing more code patterns, and many more. Right now we write all values back to memory at the end of every loop, for example, so there are some easy wins available in avoiding that — perhaps 2-3x on tight loop performance.

There’s lots more to write about why we chose tracing as the path to future performance, what to expect in terms of future work, how these sorts of performance gains can translate into new web experiences and capabilities, and what we’ve learned along the way. (One example out of left field: the static analysis tools are written in JavaScript, and apparently they are immensely faster due to even the current JIT work.) Look for posts about that from myself and other TraceMonkey hackers soon.

If you’re the sort of person who reads computer science papers, you may find the Hotpath paper to be of interest: it’s a great paper, and a great introduction to the art and science of tracing.

Thanks are especially due to Brendan, Andreas and David for making it fun to be the dumbest guy on the team; Andreas’ colleagues at UCI (Michael Franz, Mason Chang, Michael Bebenita, Gregor Wagner) for their advice and help; Ed Smith and the Adobe Tamarin team for their tech and wisdom; Rob Sayre, Vlad Vukicevic, Blake Kaplan, Boris Zbarsky and Bob Clary for testing and timely guidance; and the Mozilla developer community for letting us hold the tree closed for more than a day to get it landed.

24 comments to “the birth of a faster monkey”

  1. j2
    entered 22 August 2008 @ 3:51 pm

    Hey Mike, looks cool. That hotpath paper disappeared quickly, it seems. (Your blog must be SO popular ;-))

  2. entered 22 August 2008 @ 8:58 pm

    Glad to see my alma mater UC Irvine connected to such good things… :)

  3. entered 23 August 2008 @ 2:18 am

    I, for one, welcome our new tracing overlords.

  4. Kurt
    entered 23 August 2008 @ 6:22 am

    This sounds fascinating. I’m going to read that tracing article when I have a moment.

    Since JS is interpreted, and you are getting this speedup, how likely do you think that applying it to other dynamic languages would generate similar results (specifically PHP)? I know python has most of the speed critical sections in native code already, but perhaps for the still interpreted pieces it would be helpful too.

    Am I crazy and completely off base? Or is this a realistic thing? I am not volunteering, I certainly don’t have the skills :)

    KG

  5. jmdesp
    entered 24 August 2008 @ 4:23 pm

    It’s amazingly fast.

    But the bugs are lot of fun too, they make me feel like I’m testing a M release of Mozilla again :-) Crash when opening application’s menu items (451986), content of web pages modified (451992) ;-)

  6. entered 24 August 2008 @ 4:26 pm

    this looks really nice bit of researched work it would be intresting to compare it to SquirrelFish which has copy propagation built into it.

    regards

    John Jones http://www.johnjones.me.uk

  7. pd
    entered 25 August 2008 @ 10:25 am

    First, CONGRATULATIONS!

    The big question remaining in my mind though, is, cross browser?

    Whilst it is sensational to have JS approaching C performance, as a web developer, I’m left wondering if we’ll have to code conservatively for non-Firefox browsers as opposed to pushing JS performance for users of Firefox?

    Is it possible that this technique can be shoehorned into the IronMonkey (is that the one that aims to get Firefox JS into IE?) project and therefore IE?

    Once again, superb work. I now have one more reason to expell Flash from all the sites in my organisation.

  8. Raj
    entered 25 August 2008 @ 12:02 pm

    Wonder how this compares to the new proposed JS subsystem for Safari? http://webkit.org/blog/189/announcing-squirrelfish/

    It’s sad that noone even cares about IE anymore (least of all, Microsoft).

  9. Sergio
    entered 25 August 2008 @ 5:02 pm

    Awesome, i look forward to the TraceMonkey vs. SquirrelFish wars! Competition is good!

  10. entered 25 August 2008 @ 5:31 pm

    Great! Is there any comparison with Webkit?

  11. entered 25 August 2008 @ 5:48 pm

    Yay for dramatic improvements!

  12. entered 26 August 2008 @ 6:42 am

    “TraceMonkey landed in the Firefox 3.1 development tree, configured off by default.” How do we enable it?

  13. Hakime
    entered 26 August 2008 @ 9:46 am

    “Great! Is there any comparison with Webkit?”

    Well on my macbook pro 2.4 ghz with 2 GB of Ram, the latest Safari 4 build (with SquirrelFish built in) scores 1724.6 ms in SunSpider!!

  14. mark estes
    entered 26 August 2008 @ 10:59 am

    Will 3.1 allow Firefox to “play more nicely” with Acrobat?

  15. tim
    entered 27 August 2008 @ 5:27 am

    My mind is blowing.

  16. entered 29 August 2008 @ 11:43 am

    Dear xlinux, read JohnResig’s blog, but here is the answer ‘If you want to try these out for yourself, just snag a nightly of Firefox 3.1, open about:config, and set the following preference to true: javascript.options.jit.content’

  17. entered 29 August 2008 @ 11:45 am

    By the way, I compared Firefox 3.1 and IE8 beta in compatibility on our CMS system. IE8 did really awful. Minefield did great, with and without the JIT compiler. We did not really feel the difference, but at least it worked, and that is important.

  18. justchuck69
    entered 16 October 2008 @ 9:40 am

    Birotom

    Dear xlinux, read JohnResig’s blog, but here is the answer ‘If you want to try these out for yourself, just snag a nightly of Firefox 3.1, open about:config, and set the following preference to true: javascript.options.jit.content’

    i just downloaded the beta yesterday and mine was set to true and it was faster than firefox 3.0.3

  19. entered 20 December 2008 @ 2:29 pm

    Awesome, i look forward to the TraceMonkey vs. SquirrelFish wars! Competition is good!

  20. entered 20 December 2008 @ 2:29 pm

    I, for one, welcome our new tracing overlords…

  21. entered 21 December 2008 @ 10:25 am

    Great! Is there any comparison with Webkit?

  22. entered 9 January 2009 @ 6:21 am

    Will 3.1 allow Firefox to “play more nicely” with Acrobat?

  23. entered 30 May 2009 @ 11:25 am

    Impressive results! The gcc benchmark kicks ass :) I’ll be looking forward for future updates.

  24. entered 19 August 2009 @ 6:32 pm

    Since JS is interpreted, and you are getting this speedup, how likely do you think that applying it to other dynamic languages would generate similar results (specifically PHP)? I know python has most of the speed critical sections in native code already, but perhaps for the still interpreted pieces it would be helpful too.