views:

1537

answers:

2

I'm not sure whether to use :first or :eq(0) in a selector. I'm pretty sure that they'll always return the same object, but is one speedier than the other?

I'm sure someone here must have benchmarked these selectors before and I'm not really sure the best way to test if one is faster.

Update: here's the bench I ran:

/* start bench */
for (var count = 0; count < 5; count++) {
    var i = 0, limit = 10000;
    var start, end;
    start = new Date();
    for (i = 0; i < limit; i++) {
        var $radeditor = $thisFrame.parents("div.RadEditor.Telerik:eq(0)");
    }
    end = new Date();
    alert("div.RadEditor.Telerik:eq(0) : " + (end-start));
    var start = new Date();
    for (i = 0; i < limit; i++) {
        var $radeditor = $thisFrame.parents("div.RadEditor.Telerik:first");
    }
    end = new Date();
    alert("div.RadEditor.Telerik:first : " + (end-start));
    start = new Date();
    for (i = 0; i < limit; i++) {
        var radeditor = $thisFrame.parents("div.RadEditor.Telerik")[0];
    }
    end = new Date();
    alert("(div.RadEditor.Telerik)[0] : " + (end-start));
    start = new Date();
    for (i = 0; i < limit; i++) {
        var $radeditor = $($thisFrame.parents("div.RadEditor.Telerik")[0]);
    }
    end = new Date();
    alert("$((div.RadEditor.Telerik)[0]) : " + (end-start));
}
/* end bench */

I assumed that the 3rd would be the fastest and the 4th would be the slowest, but here's the results that I came up with:

FF3:    :eq(0) :first [0] $([0])
trial1  5275 4360 4107 3910
trial2  5175 5231 3916 4134
trial3  5317 5589 4670 4350
trial4  5754 4829 3988 4610
trial5  4771 6019 4669 4803
Average 5258.4 5205.6 4270 4361.4

IE6:    :eq(0) :first [0] $([0])
trial1  13796 15733 12202 14014
trial2  14186 13905 12749 11546
trial3  12249 14281 13421 12109
trial4  14984 15015 11718 13421
trial5  16015 13187 11578 10984
Average 14246 14424.2 12333.6 12414.8

I was correct about just returning the first native DOM object being the fastest ([0]), but I can't believe the wrapping that object in the jQuery function was faster that both :first and :eq(0)!

Unless I'm doing it wrong.

+3  A: 

Yes they are equivalent.

No they aren't likely to be significantly different (anything else is micro-optimization).

cletus
+2  A: 

Good question, great post. I tested this some while ago and couldn't remember the exact outcome. I'm really glad to have found this because it's precisely what I was looking for.

I would guess that the reason for :first and :eq(0) being a tad slower is most likely related to parsing performance. Omitting these allows the jQuery engine to utilize the native getElementsByTagName and getElementsByClassName functions.

No surprises i.t.o. the DOM element being the fastest to access. Wrapping the DOM element with jQuery in a for loop won't necessarily have an adverse effect on performance as jQuery makes use of an expando property for caching purposes.

However, it would be interesting to see how get(0) compares with DOM element access and how the jQuery wrapping thereof fares against eq(0) and the rest of the results.

Wynand