mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 1291463: Apply TypedArray sort optimisations to normal Array sort. r=jorendorff
Also change the temporary buffer to a normal Array to ensure the `Merge` helper is called with the same object class. Differential Revision: https://phabricator.services.mozilla.com/D24712 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
091478789a
commit
42c851b033
@ -221,45 +221,40 @@ function SwapArrayElements(array, i, j) {
|
||||
}
|
||||
|
||||
// A helper function for MergeSort.
|
||||
function Merge(list, start, mid, end, lBuffer, rBuffer, comparefn) {
|
||||
var i, j, k;
|
||||
//
|
||||
// Merge comparefn-sorted slices list[start..<=mid] and list[mid+1..<=end],
|
||||
// storing the merged sequence in out[start..<=end].
|
||||
function Merge(list, out, start, mid, end, comparefn) {
|
||||
// Skip lopsided runs to avoid doing useless work.
|
||||
// Skip calling the comparator if the sub-list is already sorted.
|
||||
if (mid >= end || comparefn(list[mid], list[mid + 1]) <= 0) {
|
||||
for (var i = start; i <= end; i++) {
|
||||
_DefineDataProperty(out, i, list[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var sizeLeft = mid - start + 1;
|
||||
var sizeRight = end - mid;
|
||||
|
||||
// Copy our virtual lists into separate buffers.
|
||||
for (i = 0; i < sizeLeft; i++)
|
||||
lBuffer[i] = list[start + i];
|
||||
|
||||
for (j = 0; j < sizeRight; j++)
|
||||
rBuffer[j] = list[mid + 1 + j];
|
||||
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
k = start;
|
||||
while (i < sizeLeft && j < sizeRight) {
|
||||
if (comparefn(lBuffer[i], rBuffer[j]) <= 0) {
|
||||
list[k] = lBuffer[i];
|
||||
var i = start;
|
||||
var j = mid + 1;
|
||||
var k = start;
|
||||
while (i <= mid && j <= end) {
|
||||
var lvalue = list[i];
|
||||
var rvalue = list[j];
|
||||
if (comparefn(lvalue, rvalue) <= 0) {
|
||||
_DefineDataProperty(out, k++, lvalue);
|
||||
i++;
|
||||
} else {
|
||||
list[k] = rBuffer[j];
|
||||
_DefineDataProperty(out, k++, rvalue);
|
||||
j++;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
// Empty out any remaining elements in the buffer.
|
||||
while (i < sizeLeft) {
|
||||
list[k] = lBuffer[i];
|
||||
i++;
|
||||
k++;
|
||||
// Empty out any remaining elements.
|
||||
while (i <= mid) {
|
||||
_DefineDataProperty(out, k++, list[i++]);
|
||||
}
|
||||
|
||||
while (j < sizeRight) {
|
||||
list[k] = rBuffer[j];
|
||||
j++;
|
||||
k++;
|
||||
while (j <= end) {
|
||||
_DefineDataProperty(out, k++, list[j++]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,25 +291,33 @@ function MergeSort(array, len, comparefn) {
|
||||
}
|
||||
|
||||
// We do all of our allocating up front
|
||||
var lBuffer = new List();
|
||||
var rBuffer = new List();
|
||||
var lBuffer = denseList;
|
||||
var rBuffer = [];
|
||||
|
||||
var mid, end;
|
||||
for (var windowSize = 1; windowSize < denseLen; windowSize = 2 * windowSize) {
|
||||
for (var start = 0; start < denseLen - 1; start += 2 * windowSize) {
|
||||
assert(windowSize < denseLen, "The window size is larger than the array denseLength!");
|
||||
// Use insertion sort for initial ranges.
|
||||
var windowSize = 4;
|
||||
for (var start = 0; start < denseLen - 1; start += windowSize) {
|
||||
var end = std_Math_min(start + windowSize - 1, denseLen - 1);
|
||||
InsertionSort(lBuffer, start, end, comparefn);
|
||||
}
|
||||
|
||||
for (; windowSize < denseLen; windowSize = 2 * windowSize) {
|
||||
for (var start = 0; start < denseLen; start += 2 * windowSize) {
|
||||
// The midpoint between the two subarrays.
|
||||
mid = start + windowSize - 1;
|
||||
var mid = start + windowSize - 1;
|
||||
|
||||
// To keep from going over the edge.
|
||||
end = start + 2 * windowSize - 1;
|
||||
end = end < denseLen - 1 ? end : denseLen - 1;
|
||||
// Skip lopsided runs to avoid doing useless work
|
||||
if (mid > end)
|
||||
continue;
|
||||
Merge(denseList, start, mid, end, lBuffer, rBuffer, comparefn);
|
||||
var end = std_Math_min(start + 2 * windowSize - 1, denseLen - 1);
|
||||
|
||||
Merge(lBuffer, rBuffer, start, mid, end, comparefn);
|
||||
}
|
||||
|
||||
// Swap both lists.
|
||||
var swap = lBuffer;
|
||||
lBuffer = rBuffer;
|
||||
rBuffer = swap;
|
||||
}
|
||||
MoveHoles(array, len, denseList, denseLen);
|
||||
MoveHoles(array, len, lBuffer, denseLen);
|
||||
return array;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user