Changeset 183749 in webkit
- Timestamp:
- May 4, 2015 10:27:34 AM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r183738 r183749 1 2015-05-01 Geoffrey Garen <ggaren@apple.com> 2 3 REGRESSION(r183570): jslib-traverse-jquery is 22% slower 4 https://bugs.webkit.org/show_bug.cgi?id=144476 5 6 Reviewed by Sam Weinig. 7 8 jslib-traverse-jquery is now 31% faster than its unregressed baseline. 9 10 The jQuery algorithm for sorting DOM nodes is so pathologically slow that, 11 to my knowledge, the topic of how to optimize it is not covered in any 12 literature about sorting. 13 14 On the slowest jQuery sorting test -- prevAll -- our new 15 Array.prototype.sort, compared to its predecessor, performed 12% fewer 16 comparisons and requireed 10X less overhead per comparison. Yet, it was 17 slower. 18 19 It was slower because it inadvertantly increased the average cost of the 20 comparison function by 2X. jQuery uses compareDocumentPosition to compare 21 DOM nodes, and compareDocumentPosition(a, b) is O(N) in the distance 22 required to traverse backwards from b to a. In prevAll, we encounter the 23 worst case for merge sort of compareDocumentPosition: A long list of DOM 24 nodes in mostly reverse order. In this case, merge sort will sequentially 25 compareDocumentPosition(a, b), where a is not reachable backwards from 26 b, and therefore compareDocumentPosition will traverse the whole sibling 27 list. 28 29 The solution is simple enough: Call compareDocumentPosition(b, a) instead. 30 31 This is a pretty silly thing to do, but it is harmless, and jQuery is 32 popular, so let's do it. 33 34 We do not risk suffering the same problem in reverse when sorting a long 35 list of DOM nodes in forward order. (We still have a 37% speedup on the 36 nextAll benchmark.) The reason is that merge sort performs 2X fewer 37 comparisons when the list is already sorted, so we can worry less about 38 the cost of each comparison. 39 40 A fully principled soultion to this problem would probably do something 41 like Python's timsort, which special-cases ordered ranges to perform 42 only O(n) comparisons. But that would contradict our original 43 goal of just having something simple that works. 44 45 Another option is for elements to keep a compareDocumentPosition cache, 46 like a node list cache, which allows you to determine the absolute 47 position of a node using a hash lookup. I will leave this as an exercise 48 for kling. 49 50 * builtins/Array.prototype.js: 51 (sort.merge): Compare in an order that is favorable to a comparator 52 that calls compareDocumentPosition. 53 1 54 2015-05-04 Csaba Osztrogonác <ossy@webkit.org> 2 55 -
trunk/Source/JavaScriptCore/builtins/Array.prototype.js
r183570 r183749 399 399 for (var dstIndex = left; dstIndex < rightEnd; ++dstIndex) { 400 400 if (right < rightEnd) { 401 if (left >= leftEnd || comparator(src[ left], src[right]) >0) {401 if (left >= leftEnd || comparator(src[right], src[left]) < 0) { 402 402 dst[dstIndex] = src[right++]; 403 403 continue;
Note: See TracChangeset
for help on using the changeset viewer.