From 5fb47c2ddcfee43a1bb9addbd3fa5c17d78e10ba Mon Sep 17 00:00:00 2001 From: tom910 Date: Tue, 30 Mar 2021 23:08:07 +0300 Subject: [PATCH 1/2] Improve MinHeap implementation Migrated to a new algorithm that does not go beyond the array, thus de-optimization of this piece of code is not happening --- packages/scheduler/src/SchedulerMinHeap.js | 89 +++++++++++----------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/packages/scheduler/src/SchedulerMinHeap.js b/packages/scheduler/src/SchedulerMinHeap.js index 03d82f4df65c..177681421cf5 100644 --- a/packages/scheduler/src/SchedulerMinHeap.js +++ b/packages/scheduler/src/SchedulerMinHeap.js @@ -20,72 +20,71 @@ export function push(heap: Heap, node: Node): void { } export function peek(heap: Heap): Node | null { - const first = heap[0]; - return first === undefined ? null : first; + return heap.length === 0 ? null : heap[0]; } export function pop(heap: Heap): Node | null { - const first = heap[0]; - if (first !== undefined) { - const last = heap.pop(); - if (last !== first) { - heap[0] = last; - siftDown(heap, last, 0); - } - return first; - } else { + if (heap.length === 0) { return null; } + const first = heap[0]; + + const last = heap.pop(); + + if (last !== first) { + heap[0] = last; + siftDown(heap, last, 0); + } + + return first; } function siftUp(heap, node, i) { let index = i; - while (true) { + + while (index > 0) { const parentIndex = (index - 1) >>> 1; const parent = heap[parentIndex]; - if (parent !== undefined && compare(parent, node) > 0) { - // The parent is larger. Swap positions. - heap[parentIndex] = node; - heap[index] = parent; - index = parentIndex; - } else { - // The parent is smaller. Exit. - return; + + if (compare(parent, node) < 0) { + break; } + swap(heap, parentIndex, index); + index = parentIndex; } } function siftDown(heap, node, i) { let index = i; - const length = heap.length; - while (index < length) { - const leftIndex = (index + 1) * 2 - 1; - const left = heap[leftIndex]; - const rightIndex = leftIndex + 1; - const right = heap[rightIndex]; - - // If the left or right node is smaller, swap with the smaller of those. - if (left !== undefined && compare(left, node) < 0) { - if (right !== undefined && compare(right, left) < 0) { - heap[index] = right; - heap[rightIndex] = node; - index = rightIndex; - } else { - heap[index] = left; - heap[leftIndex] = node; - index = leftIndex; - } - } else if (right !== undefined && compare(right, node) < 0) { - heap[index] = right; - heap[rightIndex] = node; - index = rightIndex; - } else { - // Neither child is smaller. Exit. - return; + const halfLength = heap.length >>> 1; + + while (index < halfLength) { + let bestIndex = index * 2 + 1; + const rightIndex = index * 2 + 2; + + // If the right node is smaller, swap with the smaller of those. + if ( + heap.length > rightIndex && + compare(heap[rightIndex], heap[bestIndex]) < 0 + ) { + bestIndex = rightIndex; + } + + if (compare(node, heap[bestIndex]) < 0) { + break; } + + swap(heap, bestIndex, index); + index = bestIndex; } } +function swap(heap, left, right) { + const item = heap[left]; + heap[left] = heap[right]; + heap[right] = item; +} + function compare(a, b) { // Compare sort index first, then task id. const diff = a.sortIndex - b.sortIndex; From 49d3249d8aa643dbc23f3b25c8266118a238b66d Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Mon, 5 Apr 2021 22:32:28 -0500 Subject: [PATCH 2/2] Revert unrelated changes --- packages/scheduler/src/SchedulerMinHeap.js | 66 +++++++++++----------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/packages/scheduler/src/SchedulerMinHeap.js b/packages/scheduler/src/SchedulerMinHeap.js index 177681421cf5..3a562b44cdb3 100644 --- a/packages/scheduler/src/SchedulerMinHeap.js +++ b/packages/scheduler/src/SchedulerMinHeap.js @@ -28,63 +28,63 @@ export function pop(heap: Heap): Node | null { return null; } const first = heap[0]; - const last = heap.pop(); - if (last !== first) { heap[0] = last; siftDown(heap, last, 0); } - return first; } function siftUp(heap, node, i) { let index = i; - while (index > 0) { const parentIndex = (index - 1) >>> 1; const parent = heap[parentIndex]; - - if (compare(parent, node) < 0) { - break; + if (compare(parent, node) > 0) { + // The parent is larger. Swap positions. + heap[parentIndex] = node; + heap[index] = parent; + index = parentIndex; + } else { + // The parent is smaller. Exit. + return; } - swap(heap, parentIndex, index); - index = parentIndex; } } function siftDown(heap, node, i) { let index = i; - const halfLength = heap.length >>> 1; - + const length = heap.length; + const halfLength = length >>> 1; while (index < halfLength) { - let bestIndex = index * 2 + 1; - const rightIndex = index * 2 + 2; - - // If the right node is smaller, swap with the smaller of those. - if ( - heap.length > rightIndex && - compare(heap[rightIndex], heap[bestIndex]) < 0 - ) { - bestIndex = rightIndex; - } - - if (compare(node, heap[bestIndex]) < 0) { - break; + const leftIndex = (index + 1) * 2 - 1; + const left = heap[leftIndex]; + const rightIndex = leftIndex + 1; + const right = heap[rightIndex]; + + // If the left or right node is smaller, swap with the smaller of those. + if (compare(left, node) < 0) { + if (rightIndex < length && compare(right, left) < 0) { + heap[index] = right; + heap[rightIndex] = node; + index = rightIndex; + } else { + heap[index] = left; + heap[leftIndex] = node; + index = leftIndex; + } + } else if (rightIndex < length && compare(right, node) < 0) { + heap[index] = right; + heap[rightIndex] = node; + index = rightIndex; + } else { + // Neither child is smaller. Exit. + return; } - - swap(heap, bestIndex, index); - index = bestIndex; } } -function swap(heap, left, right) { - const item = heap[left]; - heap[left] = heap[right]; - heap[right] = item; -} - function compare(a, b) { // Compare sort index first, then task id. const diff = a.sortIndex - b.sortIndex;