Prototype and jQuery benchmarked 668 days ago 

Disclaimer: this benchmarks are not meant to demonstrate anything. This is not a “A is better than B” sort of thing. I think this is one of my first (no, uhm, it’s THE first) benchmark I ever did, so it is all but rigorous.

Speaking of JavaScript frameworks, I’ve used prototype very much, as a Ruby on Rails programmer. But, recently, I (re)tried jQuery. I was not so impressed, when it came to light but now, hey, it has been evolved in something GREAT (and, when I say “great”, I mean it has a lot of plugins ready to use and a marvellous documentation).

What jQuery “adopters” like most of it, is its ability to scan your document by using the well known CSS selector syntax (or xpath as well!). Yes, plain as I can write $(‘#content p.warning’). This is absolutely killer.

Reading some jQuery vs Prototype comparison and around, two major things spot:

  • Prototype (>= 1.5) has CSS selector syntax too!
  • jQuery is orribly SLOW

Mmmh, interesting. So, what about some nifty benchmarks?

I then got the same HTML and the same javascript functional test and ran them with the latest jQuery and the latest Prototype library version (1.0.1 and 1.5 respectively). The tests were all focused on selecting things, not anything fancy.

This is the list of test I ran:

  • select elements by a type selector (html element). Element selected (1000 times)
  • select elements by a type selector (html element). No element selected (1000 times)
  • select elements by a simple class selector. The class name does not exist (5000 times)
  • select elements by a simple class selector. The class name does exist (5000 times)
  • select elements by a simple id selector. The id does not exist (5000 times)
  • select elements by a simple id selector. The id does exist (5000 times)
  • select elements by a descendant selector (no elements selected) (1000 times)
  • select elements by a descendant selector (20 elements selected) (1000 times)
  • select 20 elements by a id selector and bind an event handler to each one (100 times)
  • select 20 elements by a class selector and add an addictional class name to each one (1000 times)

I think that those are the majority of cases where selectors are involved.

Tests were ran on my personal desktop PC using Firefox 1.5.0.7. Each test was run at least three times. So, presented times are a simple average (approx to seconds). Timing has been done with the console.time() function from the Firebug extension.

So, here come the n-u-m-b-e-r-s.

Test Prototype 1.5_rc jQuery 1.0.1
$(‘p’)
1 selected
1000 times
23 41
$(‘img’)
None selected
1000 times
20 39
$(‘.test’)
None selected
5000 times
75 97
$(‘.test’)
1 selected
5000 times
29 29
$(‘#test’)
None selected
5000 times
20 8
$(‘#test’)
1 selected
5000 times
12 9
$(‘#test .test’)
None selected
5000 times
19 21
$(‘#test .test’)
20 selected
5000 times
95 89
Bind an event [1]
20 selected
100 times
23 20
Add a class [2]
20 selected
1000 times
28 22

Conclusions (imho):

Mmmh… so jquery is not that slow (if you compare the same functionality with prototype).

Are these tests significative? I don’t know. I did them for fun, but I see a nice pattern over there: there is a strange sort of “difficulty” trying to select something that does not exist.

The type of test, by itself, I think could be significative when testing frameworks that does a lot (try their best to) about “selecting things” in your document.

» Note 1 (for the add event test): this is the code used to run this test:

// For jquery:

    for (var i=0; i < 100; i++) {
      $('#test').bind('click', function() { alert(this) })
    }

// For prototype:
    for (var i=0; i < 100; i++) {
      $$('#test').each(function (el) {
        Event.observe(el, 'click', function() { alert(this) }, true)
      }
      )
    }

» Note 2 (for the add class test): this is the code used to run this test:

// For jquery:
    for (var i=0; i < 1000; i++) {
      $('.test').addClass('another')
    }

// For prototype:

    for (var i=0; i < 1000; i++) {
      $$('.test').each(function(el) { Element.addClassName(el, 'another') })
    }

» Note 3 this is the code used to run a test on a selector:

// For jquery:
    for (var i=0; i < 5000; i++) {
      $('#test')
    }

// For prototype:
    for (var i=0; i < 5000; i++) {
      $$('#test')
    }

What to do now

Benchmarks are boring and (mostly) useless… but what about run the same benchmark against Yahoo! UI? And why not within other “host environments (read: browsers)”?

Comments

  1. MichalT said:

    Why don’t you post the source code for the tests? I’m very interested how my own selector functions rate against the rest of the world.

    Posted on 10/15/06 09:29 PM    #

  2. Dean Edwards said:

    Let me guess. You performed these tests on a page with very few elements. Prototype is very good at executing lots of little queries. It is very bad at executing lots of large queries. Please post your source code.

    Posted on 10/16/06 12:06 AM    #

  3. Claudio said:

    @Dean: yes. Tests are very simple, as I disclaimed. I’m not into “benchmarks”, plots and that sort of thing… I needed only to prove something very raw. It’s just a step on the path. Serious benchmarks are also very time spending task… and spare time is too little :(

    @MichalT and @Dean: code is here http://claudio.cicali.org/files/benchmark_j.html
    http://claudio.cicali.org/files/benchmark.html

    One file for prototype and one for jquery.

    HTML is as when the last test was run.

    Posted on 10/16/06 12:29 AM    #

  4. Dean Edwards said:

    Try buidling a page with ten thousand nodes then run the tests again…

    Posted on 10/16/06 01:10 AM    #

  5. kenrick said:

    Im surprised you have not already done that Dean, as you have your cssQuery and similiar projects up and about, I would be interested to see your take on these popular libraries at some point.

    Posted on 10/16/06 04:02 AM    #

  6. MichalT said:

    I’ve tested those two (in Firefox 2 RC2), adding my own routines for comparision, and:

    jQuery: 6 x best, 2 x worse
    Proto: 3 x best, 4 x worse
    mine: 1 x best, 4 x worse

    This it confirms your findings (jQuery isn’t slower than Prototype), but I think it also shows that there is room for improvement in both jQuery and Prototype.

    Posted on 10/16/06 05:58 AM    #

  7. MichalT said:

    * worse = worst

    Posted on 10/16/06 05:58 AM    #

  8. MichalT said:

    Btw, the numbers (you need Google login): http://spreadsheets.google.com/ccc?key=pvxAdMvfYeUI1YwQFxJHdRw

    Posted on 10/16/06 06:02 AM    #

  9. Rey Bango said:

    @Claudio:
    MichalT results seem to contradict some of your findings. You can see the results here:

    Via Google Spreadsheet:
    http://0nz.spreadsheets.google.com/ccc?id=o04790098234894520511.5178455417629729589.12842749026303919978.6392792159332293656#

    or for those without access to a Google login:
    http://www.intoajax.com/pvjcompare.jpg

    Posted on 10/16/06 02:45 PM    #

  10. MichalT said:

    Well, the differences are completely understandable due to differences in browser versions etc. But what I wanted to point out is that my (non-optimized, barely working) code performs better than the cream-de-la-cream of Javascript libraries, so there’s room for improvement in general.

    Posted on 10/16/06 09:54 PM    #

  11. MichalT said:

    *performs better only in a few cases of course

    Posted on 10/16/06 09:55 PM    #

  12. el_vartauy said:

    what about:

    $$(‘#test:click’).each(function (el) { alert(this);})

    Posted on 10/17/06 05:13 PM    #

  13. el_vartauy said:

    (one detail from the previous post, this event selector works with the patch i mention later on that post.)
    said this…

    i think this type of test doesn’t reflect the real world use of those functions.
    the sensible selections are the class based ones, and they shouldn’t be tested in a loop over a ‘simple’ dom tree.

    one question: did you tested the prototype selector patch?
    http://www.sylvainzimmer.com/index.php/archives/2006/06/25/speeding-up-prototypes-selector/

    in my usecase the speed of prototype without the patch is so slow that firefox alert me about the uresponsive script, and jQuery is faster.
    Prototype with the patch is faster than jQuery.

    my usecase:

    console.time(‘test performance’);
    $$(‘a.popup’);
    console.timeEnd(‘test performance’);

    console.time(‘test performance’);
    $(‘a.popup’);
    console.timeEnd(‘test performance’);

    Prototype: 550ms
    Prototype+patch: 60ms
    jQuery: 115ms


    var total=0; console.time(‘test performance’); $$(‘*’).each(function(){ total=total+1; }); console.timeEnd(‘test performance’); console.debug(total);
    2720 items selected.

    var total=0; console.time(‘test performance’); $$(‘a.popup’).each(function(){ total=total+1; }); console.timeEnd(‘test performance’); console.debug(total);
    298 items selected.

    Posted on 10/17/06 06:20 PM    #

commenting closed for this article

This site

Browse by category

Contacts

Feed from feedburner Subscribe to this feed with Bloglines

Creative Commons

XFN Friendly