On Feb 17, 2:43 am, John Resig <jere...@gmail.com> wrote:

> On Mon, Feb 16, 2009 at 8:28 AM, RobG <rg...@iinet.net.au> wrote:
>
> > On Feb 16, 5:30 pm, SteelRing <steelr...@gmail.com> wrote:
> >> This may sound stupid to y'all jquery practitioners, but i wonder
> >> which method is fastest (recommended) for selecting a cell with a
> >> class in a big table (think like 1000+ rows 100+ columns):
>
> > Fastest: the browser-native getElementsByClassName  (recent Firefox,
> > Opera, Safari) is 20 to 40 times faster than $('.className'), as a
> > bonus you get a live collection.
>
> > Alternatively, XPath is probably just as quick but the result isn't
> > live (supported by the same set of browsers).
>
> > The jQuery way is to use a CSS selector, however it is much slower
> > than other methods (except perhaps in IE).
>
> >> ("#tableid tbody tr.rowclass td.cellclass") or is it ("td.cellclass")
> >> or (".cellclass").
>
> >> And how about if the cell happens to have a unique id:
>
> >> ("#tableid tbody tr#uniquerow td#uniqueid") or just ("#uniqueid")
>
> > If speed really matters, getElementById is more than 7 times faster
> > than $('#...') in Firefox and  4 times faster in Safari.
>
> >> Philosophically, the question being is it better to put as much detail
> >> as structurally already known by the programmer into the selector or
> >> just anything goes and let jquery handle it as long as it works.
>
> > There is no selector optimisation that I can see in jQuery other than
> > using getElementById after discovering '#...' (and the overhead of
> > discovering that means it is 4 to 6 times slower than gEBI).

> Umm - that's not true at all.

Which part?  Are you referring to selector optimisation or that $()
isn't slower?


> I created a test for you to 
> see:http://dev.jquery.com/~john/ticket/class-speed/
>
> In Firefox 3 I'm getting:
> ID Raw: 9 ID jQuery: 22 (over 500 queries)
> Class Raw: 1108 Class jQuery: 778 (over 100 queries)
>
> In Safari 3.2 I'm getting:
> ID Raw: 1 ID jQuery: 3 (over 500 queries)
> Class Raw: 224 Class jQuery: 184 (over 100 queries)

Interesting, here's my results:

Safari 3.2, 1GHz PowerPc G4:
ID Raw: 7 ID jQuery: 23
Class Raw: 1744 Class jQuery: 5361

Browser-native is 3 times faster for both.


Mobile Safari, iPhone 3G:
ID Raw: 95 ID jQuery: 296
Class Raw: 8789 Class jQuery: 34594

Browser-native is 3 times faster for ID,  4 times for class.


Firefox 3.0, 3GHz P4:
ID Raw: 11 ID jQuery: 27
Class Raw: 1579 Class jQuery: 1141

Browser-native is nearly 3 times faster for ID, 40% slower for class.



Safari 3.2,  3GHz P4:
ID Raw: 5 ID jQuery: 11
Class Raw: 249 Class jQuery: 1107

Browser-native is 2 times faster for ID, 5 times faster for class.


> So not only is jQuery's class implementation faster

According to my tests, only in Firefox so I have reservations about
that.


> but the ID
> searching has an approximately 0.026 milliseconds overhead - that's
> 2.6% of 1 millisecond per query - an absolutely acceptable figure to
> be able to live with.

The speed for a single call isn't really an issue; it's the relative
performance, particularly on low specification hardware.  Getting an
element by ID is usually a single call so $(#) is "fast enough" for
most cases.  The speed penalty is relevant when there is a requirement
to do many quickly.

The test of the class selector seems a bit trivial: whenever a
javascript method is faster than its browser-native equivalent further
investigation is called for.  If the selector is forced to do a bit of
work by nesting the elements that it must find, the speed advantage in
Firefox is pretty quickly nullified.

The test below randomises the ID so 90% of the time it will be
different to the one previous, the class name 33%.

Optimising the class selector may improve performance with $(),
however it is also pretty easy to slow it down with a poorly chosen
selector.  It's speed doesn't come close to the browser-native methods
in Firefox or Safari where the elements are nested a little.

On the P4 noted above, I get:

Safari 3.2:
gEBI: 9
$(#): 30
gEBCN: 10
$(CSS selector): 85

Firefox 3.0:
gEBI: 14
$(#): 57
gEBCN: 22
$(CSS selector): 640


++++++++++++++++++++++++++++++++++++++

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd";>
<html>
<head>
  <title>jQuery selectors</title>
  <script type="text/javascript" src="jquery-1.3.1.js"></script>
  <script type="text/javascript">

   function doIt(n) {
     var numSet = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
     var numLen = numSet.length;
     var i, t0, t1, t2, t3;
     var msg = [];
     var getNum = function() {
       return (Math.random()*numLen)|0;
     }

     var classes = ['foo', 'bar', 'eke'];
     var cLen = classes.length;
     var getClass = function() {
       return '.' + classes[(Math.random()*cLen)|0];
     }

     // Test getting by ID
     i = n;
     t0 = new Date();
     while (i--) {
       document.getElementById('p' + getNum());
     }
     t1 = new Date();

     i = n;
     t2 = new Date();
     while (i--) {
       $('#p' + getNum());
     }
     t3 = new Date();

     msg.push('gEBI: ' + (t1 - t0));
     msg.push('$(#): ' + (t3 - t2));

     // Test getting by class name
     i = n;
     t0 = new Date();
     while (i--) {
       document.getElementsByClassName(getClass());
     }
     t1 = new Date();

     i = n;
     t2 = new Date();
     while (i--) {
       $('p ' + getClass());
     }
     t3 = new Date();

     msg.push('gEBCN: ' + (t1 - t0));
     msg.push('$(CSS selector): ' + (t3 - t2));

     $('#msg').html(msg.join('<br>'));
   }

   window.onload = function() {
      doIt(1000);
   }

  </script>
</head>
<body>
<p id="msg"></p>
<table><tbody>
 <tr><td>
  <p id="p0">0</p>
  <p id="p1" class="bar">1</p>
  <p id="p2">2</p>
  <p id="p3">3</p>
  <p id="p4">4</p>
 <tr><td>
  <p id="p5" class="foo">5</p>
  <p id="p6">6</p>
  <p id="p7">7</p>
  <p id="p8" class="eke">8</p>
  <p id="p9">9</p>
</table>
</body>
</html>


Feedback on the methodology or appropriateness of the tests is
welcome.


--
Rob

Reply via email to