Ritesh Chandora
Ritesh Chandora

Reputation: 8640

JQuery selector performace and comparesion issue

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

Answers (2)

DoXicK
DoXicK

Reputation: 4812

lets say you have 100 rows with GUIDs, with each 100 .cell-taskname in them, with each 100 .cell-text in them.

  • 100 GUIDS
  • 10000 .cell-taskname
  • 1000000 .cell-text

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

T.J. Crowder
T.J. Crowder

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:

  1. Make a list of all .cell-text elements.

  2. Remove ones that don't have an ancestor matching .cell-taskname from the list.

  3. 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

Related Questions