Skip to content

Commit 8b56b38

Browse files
committed
improve polyfill of stable sort
1 parent ae0cd69 commit 8b56b38

6 files changed

+53
-7
lines changed

packages/core-js/internals/array-sort.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ var toObject = require('../internals/to-object');
44
var toLength = require('../internals/to-length');
55
var fails = require('../internals/fails');
66
var arrayMethodIsStrict = require('../internals/array-method-is-strict');
7+
var FF = require('../internals/engine-ff-version');
8+
var IE_OR_EDGE = require('../internals/engine-is-ie-or-edge');
9+
var V8 = require('../internals/engine-v8-version');
10+
var WEBKIT = require('../internals/engine-webkit-version');
711

812
var test = [];
913
var nativeSort = test.sort;
@@ -21,6 +25,12 @@ var FAILS_ON_NULL = fails(function () {
2125
var STRICT_METHOD = arrayMethodIsStrict('sort');
2226

2327
var STABLE_SORT = !fails(function () {
28+
// feature detection can be too slow, so check engines versions
29+
if (V8) return V8 < 70;
30+
if (FF && FF > 3) return;
31+
if (IE_OR_EDGE) return true;
32+
if (WEBKIT) return WEBKIT < 603;
33+
2434
var result = '';
2535
var code, chr, value, index;
2636

@@ -53,14 +63,28 @@ var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_S
5363
var mergeSort = function (array, comparefn) {
5464
var length = array.length;
5565
var middle = floor(length / 2);
56-
if (length < 2) return array;
57-
return merge(
66+
return length < 8 ? insertionSort(array, comparefn) : merge(
5867
mergeSort(array.slice(0, middle), comparefn),
5968
mergeSort(array.slice(middle), comparefn),
6069
comparefn
6170
);
6271
};
6372

73+
var insertionSort = function (array, comparefn) {
74+
var length = array.length;
75+
var i = 1;
76+
var element, j;
77+
78+
while (i < length) {
79+
j = i;
80+
element = array[i];
81+
while (j && sortCompare(array[j - 1], element, comparefn) > 0) {
82+
array[j] = array[--j];
83+
}
84+
if (j !== i++) array[j] = element;
85+
} return array;
86+
};
87+
6488
var merge = function (left, right, comparefn) {
6589
var llength = left.length;
6690
var rlength = right.length;
@@ -78,9 +102,8 @@ var merge = function (left, right, comparefn) {
78102
};
79103

80104
var sortCompare = function (x, y, comparefn) {
81-
if (x === undefined && y === undefined) return 0;
82-
if (x === undefined) return 1;
83105
if (y === undefined) return -1;
106+
if (x === undefined) return 1;
84107
if (comparefn !== undefined) {
85108
return +comparefn(x, y) || 0;
86109
} return String(x) > String(y) ? 1 : -1;
@@ -103,6 +126,7 @@ module.exports = FORCED ? function sort(comparefn) {
103126
if (index in array) items.push(array[index]);
104127
}
105128

129+
// TODO: use something more complex like timsort?
106130
items = mergeSort(items, comparefn);
107131
itemsLength = items.length;
108132
index = 0;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
var userAgent = require('../internals/engine-user-agent');
2+
3+
var firefox = userAgent.match(/firefox\/(\d+)/i);
4+
5+
module.exports = !!firefox && +firefox[1];
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
var UA = require('../internals/engine-user-agent');
2+
3+
module.exports = /MSIE|Trident/.test(UA);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
var userAgent = require('../internals/engine-user-agent');
2+
3+
var webkit = userAgent.match(/AppleWebKit\/(\d+)\./);
4+
5+
module.exports = !!webkit && +webkit[1];

packages/core-js/internals/object-prototype-accessors-forced.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
var IS_PURE = require('../internals/is-pure');
33
var global = require('../internals/global');
44
var fails = require('../internals/fails');
5-
var userAgent = require('../internals/engine-user-agent');
5+
var WEBKIT = require('../internals/engine-webkit-version');
66

77
// Forced replacement object prototype accessors methods
88
module.exports = IS_PURE || !fails(function () {
99
// This feature detection crashes old WebKit
1010
// https://github.com/zloirock/core-js/issues/232
11-
var webkit = userAgent.match(/AppleWebKit\/(\d+)\./);
12-
if (webkit && +webkit[1] < 535) return;
11+
if (WEBKIT && WEBKIT < 535) return;
1312
var key = Math.random();
1413
// In FF throws only define methods
1514
// eslint-disable-next-line no-undef, no-useless-call -- required for testing

packages/core-js/modules/es.typed-array.sort.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,21 @@
22
var ArrayBufferViewCore = require('../internals/array-buffer-view-core');
33
var fails = require('../internals/fails');
44
var $sort = require('../internals/array-sort');
5+
var FF = require('../internals/engine-ff-version');
6+
var IE_OR_EDGE = require('../internals/engine-is-ie-or-edge');
7+
var V8 = require('../internals/engine-v8-version');
8+
var WEBKIT = require('../internals/engine-webkit-version');
59

610
var aTypedArray = ArrayBufferViewCore.aTypedArray;
711
var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;
812

913
var STABLE_SORT = !fails(function () {
14+
// feature detection can be too slow, so check engines versions
15+
if (V8) return V8 < 73;
16+
if (FF) return FF < 67;
17+
if (IE_OR_EDGE) return true;
18+
if (WEBKIT) return WEBKIT < 602;
19+
1020
// eslint-disable-next-line es/no-typed-arrays -- required for testing
1121
var array = new Uint16Array(516);
1222
var expected = Array(516);

0 commit comments

Comments
 (0)