Reputation: 8640
All three operation are performing same thing. can anyone explain the reason for different performance?
console.time('first');
for(guid in ALLGUID){
$('.'+guid).find('.cell-taskname').find('.cell-text').text()
}
console.timeEnd('first');
console.time('second');
for(guid in ALLGUID){
$('.'+guid).find('.cell-taskname .cell-text').text()
}
console.timeEnd('second');
console.time('third');
for(guid in ALLGUID){
$('.'+guid+' .cell-taskname .cell-text').text()
}
console.timeEnd('third');
first: ~3500.000ms
second: ~3700.000ms
third: ~38000.000ms (yes it is 38 second.)
Scenario Explanation: I have Huge table and I am iterating over all table rows. here Guid is unique key and class name of table row. cell-taskname is div inside every first column of table-row and .cell-text is span containing text.
Upvotes: 3
Views: 70
Reputation: 4812
lets say you have 100 rows with GUIDs, with each 100 .cell-taskname in them, with each 100 .cell-text in them.
selectors are done right to left, so if you would do the 3rd example:
select all .cell-text (1m)
eliminate those that don't an ancestor .cell-taskname (still 1m)
eliminate those that don't have a higher ancestor of .guid (10k)
while if you do the first one:
select all .guid (1)
find all cell-taskname in that (100)
select all cell-text in those (10000)
in the 3rd (my first) scenario, you work with 2.01m elements
in the 1st (my second) scenario, you work with only 10101 elements. So that is why it's that much faster :-)
of course, these aren't exact performance numbers, but it does explain the concept behind selector optimizations...
Upvotes: 3
Reputation: 1074138
It all has to do with the fact that selectors are processed right-to-left.
In your first and second examples, the main search of the DOM is only for the elements with the given GUID class. Then, you only search within those elements for the cells.
But in your last example, with a single selector, the engine does this:
Make a list of all .cell-text
elements.
Remove ones that don't have an ancestor matching .cell-taskname
from the list.
Remove any remaining ones that don't have an ancestor matching .<your-guid-here>
from the list.
You can see how that takes a bit longer, if there are lots of .cell-text
elements and only a few .<your-guid-here>
elements. You've said that the .<your-guid-here>
element is unique (a single row in a massive table), so the performance difference makes sense here.
More on right-to-left matching in this question and its answers.
Upvotes: 6