Which algorithm does the JavaScript Array#sort()
function use? I understand that it can take all manner of arguments and functions to perform different kinds of sorts, I'm simply interested in which algorithm the vanilla sort uses.
-
You should consider an alternate solution from the ones given.– AnthonyCommented Jun 10, 2019 at 21:01
-
6It's unspecified by the language spec and dependent on implementation. Answers in this thread are (currently) very outdated and/or specific to a particular implementation (and if they're not and not kept updated, they will become outdated). As of now, V8 7.0 uses Timsort.– ggorlenCommented Oct 6, 2020 at 22:28
7 Answers
I've just had a look at the WebKit (Chrome, Safari …) source. Depending on the type of array, different sort methods are used:
Numeric arrays (or arrays of primitive type) are sorted using the C++ standard library function std::qsort
which implements some variation of quicksort (usually introsort).
Contiguous arrays of non-numeric type are stringified and sorted using mergesort, if available (to obtain a stable sorting) or qsort
if no merge sort is available.
For other types (non-contiguous arrays and presumably for associative arrays) WebKit uses either selection sort (which they call “min” sort) or, in some cases, it sorts via an AVL tree. Unfortunately, the documentation here is rather vague so you’d have to trace the code paths to actually see for which types which sort method is used.
And then there are gems like this comment:
// FIXME: Since we sort by string value, a fast algorithm might be to use a
// radix sort. That would be O(N) rather than O(N log N).
– Let’s just hope that whoever actually “fixes” this has a better understanding of asymptotic runtime than the writer of this comment, and realises that radix sort has a slightly more complex runtime description than simply O(N).
(Thanks to phsource for pointing out the error in the original answer.)
-
3This is outdated– user3064538Commented Aug 13, 2022 at 15:27
-
At the moment I found for V8 it is std:sort when no compare function provided // Default sorting is done in C++ using std::sort and MergeSort when compare function provided TypedArrayMergeSort Commented Jul 6, 2023 at 6:09
-
...and TimSort for regular arrays third_party/v8/builtins/array-sort.tq Commented Jul 6, 2023 at 6:18
If you look at this bug 224128, it appears that MergeSort is being used by Mozilla.
-
4Well it's also wrong in that it only states an algorithm for a specific implementation. The specification makes no such claims, and other implementations use other algorithms, so this is quite misleading. Commented Nov 27, 2018 at 19:04
There is no draft requirement for JS to use a specific sorting algorthim. As many have mentioned here, Mozilla uses merge sort.However, In Chrome's v8 source code, as of today, it uses QuickSort and InsertionSort, for smaller arrays.
From Lines 807 - 891
var QuickSort = function QuickSort(a, from, to) {
var third_index = 0;
while (true) {
// Insertion sort is faster for short arrays.
if (to - from <= 10) {
InsertionSort(a, from, to);
return;
}
if (to - from > 1000) {
third_index = GetThirdIndex(a, from, to);
} else {
third_index = from + ((to - from) >> 1);
}
// Find a pivot as the median of first, last and middle element.
var v0 = a[from];
var v1 = a[to - 1];
var v2 = a[third_index];
var c01 = comparefn(v0, v1);
if (c01 > 0) {
// v1 < v0, so swap them.
var tmp = v0;
v0 = v1;
v1 = tmp;
} // v0 <= v1.
var c02 = comparefn(v0, v2);
if (c02 >= 0) {
// v2 <= v0 <= v1.
var tmp = v0;
v0 = v2;
v2 = v1;
v1 = tmp;
} else {
// v0 <= v1 && v0 < v2
var c12 = comparefn(v1, v2);
if (c12 > 0) {
// v0 <= v2 < v1
var tmp = v1;
v1 = v2;
v2 = tmp;
}
}
// v0 <= v1 <= v2
a[from] = v0;
a[to - 1] = v2;
var pivot = v1;
var low_end = from + 1; // Upper bound of elements lower than pivot.
var high_start = to - 1; // Lower bound of elements greater than pivot.
a[third_index] = a[low_end];
a[low_end] = pivot;
// From low_end to i are elements equal to pivot.
// From i to high_start are elements that haven't been compared yet.
partition: for (var i = low_end + 1; i < high_start; i++) {
var element = a[i];
var order = comparefn(element, pivot);
if (order < 0) {
a[i] = a[low_end];
a[low_end] = element;
low_end++;
} else if (order > 0) {
do {
high_start--;
if (high_start == i) break partition;
var top_elem = a[high_start];
order = comparefn(top_elem, pivot);
} while (order > 0);
a[i] = a[high_start];
a[high_start] = element;
if (order < 0) {
element = a[i];
a[i] = a[low_end];
a[low_end] = element;
low_end++;
}
}
}
if (to - high_start < low_end - from) {
QuickSort(a, high_start, to);
to = low_end;
} else {
QuickSort(a, from, low_end);
from = high_start;
}
}
};
Update As of 2018 V8 uses TimSort, thanks @celwell. Source
-
21I believe V8 is now using TimSort: github.com/v8/v8/blob/78f2610345fdd14ca401d920c140f8f461b631d1/…– celwellCommented Jan 1, 2019 at 1:18
The ECMAScript standard does not specify which sort algorithm is to be used. Indeed, different browsers feature different sort algorithms. For example, Mozilla/Firefox's sort() is not stable (in the sorting sense of the word) when sorting a map. IE's sort() is stable.
-
18Update: Recent Firefoxes have a stable
Array.sort
; see this question.– skagedalCommented Jan 24, 2012 at 13:54 -
The point is that the sorting algorithm is implementation-dependent.– seanCommented Sep 23, 2017 at 15:18
-
2For the curious, the ECMAscript standard is found here: tc39.github.io/ecma262/#sec-array.prototype.sort– BenjaminCommented Mar 8, 2019 at 20:44
Google Chrome uses TimSort, Python's sorting algorithm, as of version 70 released on September 13, 2018.
See the the post on the V8 dev blog (V8 is Chrome's JavaScript engine) for details about this change. You can read the source code or patch 1186801 specifically.
I think that would depend on what browser implementation you are refering to.
Every browser type has it's own javascript engine implementation, so it depends. You could check the sourcecode repos for Mozilla and Webkit/Khtml for different implementations.
IE is closed source however, so you may have to ask somebody at microsoft.
-
Different interpreters may do things differently in the sense that they are either buggy (i.e. it isn't on-purpose) or they add or take away features. The sort() method is a standard part of Core JavaScript and would be defined by the standard, which browsers would want to follow. Commented Oct 24, 2008 at 18:20
-
2@JasonBunting if function is implemented and does what it should do as defined in specification, browser developers are free to implement the function as they want: be it bubble or quick sort. ECMA specs do not define sort algorithm to be used. Commented Oct 24, 2008 at 18:50
After some more research, it appears, for Mozilla/Firefox, that Array.sort()
uses Merge Sort. See the code here.