JQuery selector performace and comparison problem

All three operations do the same thing. can anyone explain the reason for the 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, that's 38 seconds.)

Scenario Explanation : I have a huge table and I repeat all the rows of the table. here Guid is the unique key and class name of the table row. cell-taskname is a div inside every first column of table-row and .cell-text is a range containing text.

+3


source to share


2 answers


This is all due to the fact that selectors are processed from right to left.

In the first and second examples, basic DOM search is only for elements with a given GUID class. Then you search only within those elements for the cells.

But in the last example with one selector, the engine does it:



  • List all the items .cell-text

    .

  • Remove those that do not have an ancestor mapping .cell-taskname

    from the list.

  • Remove any remaining that do not have an ancestor match .<your-guid-here>

    from the list.

You can see how it takes a little longer if there are many items .cell-text

and only a few items .<your-guid-here>

. You said the item .<your-guid-here>

is unique (one row in a massive table), so the performance difference makes sense here.

Read more about right to left right in this question and his answers .

+6


source


lets say that you have 100 lines of GUIDs, each containing 100.cell-taskname, each containing 100.cell-text.

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

are executed from right to left, so if you do the third 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)

      

and if you do the first:



select all .guid (1)
find all cell-taskname in that (100)
select all cell-text in those (10000)

      

in the third (first) scenario, you are working with 2.01m elements

in the first (my second) scenario, you only work with 10101 items. That's why it is much faster :-)

of course these are not exact performance numbers, but it does explain the concept of selector optimization ...

+3


source