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