зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1784090 - Part 5: Avoid copying the array for ArrayToSorted. r=mgaudet
Change `MergeSort` to directly modify its input instead of creating a copy. `ArraySort` now needs to copy the input and re-arrange any holes, whereas `ArrayToSorted` can directly return the result from `MergeSort`. Depends on D154264 Differential Revision: https://phabricator.services.mozilla.com/D154265
This commit is contained in:
Родитель
324aa95386
Коммит
b4cd6b075b
|
@ -130,7 +130,29 @@ function ArraySort(comparefn) {
|
|||
var wrappedCompareFn = ArraySortCompare(comparefn);
|
||||
|
||||
// Step 5.
|
||||
return MergeSort(O, len, wrappedCompareFn);
|
||||
// To save effort we will do all of our work on a dense list, then create
|
||||
// holes at the end.
|
||||
var denseList = [];
|
||||
var denseLen = 0;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (i in O) {
|
||||
DefineDataProperty(denseList, denseLen++, O[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (denseLen < 1) {
|
||||
return O;
|
||||
}
|
||||
|
||||
var sorted = MergeSort(denseList, denseLen, wrappedCompareFn);
|
||||
|
||||
assert(IsPackedArray(sorted), "sorted is a packed array");
|
||||
assert(sorted.length === denseLen, "sorted array has the correct length");
|
||||
|
||||
MoveHoles(O, len, sorted, denseLen);
|
||||
|
||||
return O;
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.18. */
|
||||
|
@ -1401,7 +1423,12 @@ function ArrayToSorted(comparefn) {
|
|||
var wrappedCompareFn = ArraySortCompare(comparefn);
|
||||
|
||||
// Steps 6-9.
|
||||
return MergeSort(items, len, wrappedCompareFn);
|
||||
var sorted = MergeSort(items, len, wrappedCompareFn);
|
||||
|
||||
assert(IsPackedArray(sorted), "sorted is a packed array");
|
||||
assert(sorted.length === len, "sorted array has the correct length");
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -76,47 +76,35 @@ function MoveHoles(sparse, sparseLen, dense, denseLen) {
|
|||
|
||||
// Iterative, bottom up, mergesort.
|
||||
function MergeSort(array, len, comparefn) {
|
||||
// To save effort we will do all of our work on a dense list,
|
||||
// then create holes at the end.
|
||||
var denseList = [];
|
||||
var denseLen = 0;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (i in array) {
|
||||
DefineDataProperty(denseList, denseLen++, array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (denseLen < 1) {
|
||||
return array;
|
||||
}
|
||||
assert(IsPackedArray(array), "array is packed");
|
||||
assert(array.length === len, "length mismatch");
|
||||
assert(len > 0, "array should be non-empty");
|
||||
|
||||
// Insertion sort for small arrays, where "small" is defined by performance
|
||||
// testing.
|
||||
if (denseLen < 24) {
|
||||
InsertionSort(denseList, 0, denseLen - 1, comparefn);
|
||||
MoveHoles(array, len, denseList, denseLen);
|
||||
if (len < 24) {
|
||||
InsertionSort(array, 0, len - 1, comparefn);
|
||||
return array;
|
||||
}
|
||||
|
||||
// We do all of our allocating up front
|
||||
var lBuffer = denseList;
|
||||
var lBuffer = array;
|
||||
var rBuffer = [];
|
||||
|
||||
// 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);
|
||||
for (var start = 0; start < len - 1; start += windowSize) {
|
||||
var end = std_Math_min(start + windowSize - 1, len - 1);
|
||||
InsertionSort(lBuffer, start, end, comparefn);
|
||||
}
|
||||
|
||||
for (; windowSize < denseLen; windowSize = 2 * windowSize) {
|
||||
for (var start = 0; start < denseLen; start += 2 * windowSize) {
|
||||
for (; windowSize < len; windowSize = 2 * windowSize) {
|
||||
for (var start = 0; start < len; start += 2 * windowSize) {
|
||||
// The midpoint between the two subarrays.
|
||||
var mid = start + windowSize - 1;
|
||||
|
||||
// To keep from going over the edge.
|
||||
var end = std_Math_min(start + 2 * windowSize - 1, denseLen - 1);
|
||||
var end = std_Math_min(start + 2 * windowSize - 1, len - 1);
|
||||
|
||||
Merge(lBuffer, rBuffer, start, mid, end, comparefn);
|
||||
}
|
||||
|
@ -126,8 +114,7 @@ function MergeSort(array, len, comparefn) {
|
|||
lBuffer = rBuffer;
|
||||
rBuffer = swap;
|
||||
}
|
||||
MoveHoles(array, len, lBuffer, denseLen);
|
||||
return array;
|
||||
return lBuffer;
|
||||
}
|
||||
|
||||
// A helper function for MergeSortTypedArray.
|
||||
|
|
Загрузка…
Ссылка в новой задаче