【发布时间】:2016-12-08 12:27:36
【问题描述】:
我已经实现了一个合并排序和一个快速排序来将它们与原生 JavaScript 排序进行比较。对于快速排序,我尝试使用此算法:view algorithm on youtube。两种算法都使用尽可能少的内存,对于合并排序,为每个递归调用传递一个辅助数组(以避免开销),对于快速排序,开始和结束位置的位置。我正在使用排序来管理 NodeJs 应用程序中的大量数据。
下面你有合并排序、快速排序和原生 JavaScript 排序,你可以测试性能
问题是:为什么原生 JavaScript 执行速度较慢?
就我而言:
Chrome - 合并排序:测量:1997.920ms;快速排序:测量:1755.740ms;本机:测量:4988.105ms
节点:归并排序:测量:2233.413ms;快速排序:测量:1876.055ms;本机:测量:6317.118ms
合并排序
var length = 10000000; // ten millions;
var arr = [];
for (let i = length; i > 0; i--) {
// random array
arr.push(parseInt(Math.random() * 1000000000));
}
var mergeSort = function(array) {
function merge(arr, aux, lo, mid, hi) {
for (var k = lo; k <= hi; k++) {
aux[k] = arr[k];
}
var i = lo;
var j = mid + 1;
for (var k = lo; k <= hi; k++) {
if (i > mid) {
arr[k] = aux[j++];
} else if (j > hi) {
arr[k] = aux[i++];
} else if (aux[i] < aux[j]) {
arr[k] = aux[i++];
} else {
arr[k] = aux[j++];
}
}
}
function sort(array, aux, lo, hi) {
if (hi <= lo) return;
var mid = Math.floor(lo + (hi - lo) / 2);
sort(array, aux, lo, mid);
sort(array, aux, mid + 1, hi);
merge(array, aux, lo, mid, hi);
}
function merge_sort(array) {
var aux = array.slice(0);
sort(array, aux, 0, array.length - 1);
return array;
}
return merge_sort(array);
}
console.time('measure');
mergeSort(arr);
console.timeEnd('measure');
console.log(arr[0], arr[1]);
快速排序
var length = 10000000; // ten millions;
var arr = [];
for (let i = length; i > 0; i--) {
// random array
arr.push(parseInt(Math.random() * 1000000000));
}
function quickSort(arr, leftPos, rightPos, arrLength) {
let initialLeftPos = leftPos;
let initialRightPos = rightPos;
let direction = true;
let pivot = rightPos;
while ((leftPos - rightPos) < 0) {
if (direction) {
if (arr[pivot] < arr[leftPos]) {
quickSort.swap(arr, pivot, leftPos);
pivot = leftPos;
rightPos--;
direction = !direction;
} else
leftPos++;
} else {
if (arr[pivot] <= arr[rightPos]) {
rightPos--;
} else {
quickSort.swap(arr, pivot, rightPos);
leftPos++;
pivot = rightPos;
direction = !direction;
}
}
}
if (pivot - 1 > initialLeftPos) {
quickSort(arr, initialLeftPos, pivot - 1, arrLength);
}
if (pivot + 1 < initialRightPos) {
quickSort(arr, pivot + 1, initialRightPos, arrLength);
}
}
quickSort.swap = (arr, el1, el2) => {
let swapedElem = arr[el1];
arr[el1] = arr[el2];
arr[el2] = swapedElem;
}
arrLength = arr.length;
console.time('measure');
quickSort(arr, 0, arrLength - 1, arrLength);
console.log(arr[0], arr[1]);
console.timeEnd('measure');
原生 Javascript 排序
var length = 10000000; // ten millions;
var arr = [];
for (let i = length; i > 0; i--) {
// random array
arr.push(parseInt(Math.random() * 100000000));
}
console.time('measure');
arr.sort(function compareNumbers(a, b) {
return a - b;
});
console.timeEnd('measure');
console.log(arr[0], arr[1]);
【问题讨论】:
-
仅供参考,按照您编写它们的顺序,考虑到我的 PC 和随机性,第一个是最慢的,第二个是最快的 :)
-
是的,Quicksort 的执行速度是最快的.. 所以原生 js 在你的电脑上比合并排序执行得更好?
-
有趣。我在 Firefox 和 Edge 中检查了这些内容。在 Firefox 中,这三者之间的区别不大,尽管原生排序仍然是最慢的。在 Edge 中,第一个永远不会完成,或者我可能放弃得太早了。有点它似乎永远不会完成。最后两个在 Edge 中完成。
-
如果将比较器作为参数传递给自定义实现会怎样? 2 个自定义实现具有硬编码顺序,而原生实现是通用的。
-
很可能与香草排序灵活且无法利用原生比较运算符这一事实有关。如果您重写 mergeSort 和 quickSort 以使用 compareNumbers 而不是
<、>或==,我很想看看时间会是什么样子
标签: javascript node.js algorithm performance sorting