我做了一点测试,发现array.sort(function(a, b) { return a - b; });
比JavaScript中的array.sort();
要快很多。
结果令人震惊,IE9快1.7倍,FF7 1.6倍,Chrome浏览器6.7倍。
另外,通过我自己在JS中实现快速排序,我发现它甚至比上面提到的两种方法都要快。 (两种不同的实现,一种接受比较器函数作为参数,另一种不接受。两者都更快。)
有没有合理的解释?
编辑:我的实施:
没有比较者:
function quickSort(array, from, to) {
if(typeof from === 'undefined') {
from = 0;
to = array.length - 1;
}
else if(typeof to === 'undefined') {
to = array.length - 1;
}
if(to - from < 1) {
return;
}
var i = from, pivot = to, t;
while(i < pivot) {
if(array[i] > array[pivot]) {
t = array[i];
array[i] = array[pivot - 1];
array[pivot - 1] = array[pivot];
array[pivot] = t;
pivot--;
}
else {
i++;
}
}
quickSort(array, from, pivot - 1);
quickSort(array, pivot + 1, to);
}
使用比较器:
function quickSortFunc(array, sortfunc, from, to) {
if(typeof from === 'undefined') {
from = 0;
to = array.length - 1;
}
else if(typeof to === 'undefined') {
to = array.length - 1;
}
if(to - from < 1) {
return;
}
var i = from, pivot = to, t;
while(i < pivot) {
if(sortfunc(array[i], array[pivot]) > 0) {
t = array[i];
array[i] = array[pivot - 1];
array[pivot - 1] = array[pivot];
array[pivot] = t;
pivot--;
}
else {
i++;
}
}
quickSortFunc(array, sortfunc, from, pivot - 1);
quickSortFunc(array, sortfunc, pivot + 1, to);
}
答案 0 :(得分:1)
有两个因素可以发挥作用:
首先,正如Felix King在评论中提到的,本机排序方法在比较之前将每个数组成员转换为字符串。如果所有(或大多数)数组成员都是数字,则使用function(a, b) { return a - b; }
会更快。
其次,排序算法是implementation dependent。正如您可能知道或不知道的那样,如果您将新元素插入已排序的数组中,则quicksort执行非常糟糕。也许这就是为什么WebKit决定实现选择排序。
但不要害怕,帮助就在附近!有人已经forked WebKit to fix this
答案 1 :(得分:0)
很多理由都会发挥作用。不必检查变量类型是其中之一,只有其中之一。而您的实施使优化者感到高兴。它适用于密集数组,它只适用于数字,变量具有良好的范围和重用性。没有这个,没有,没有eval,没有魔术变量,属性,函数或类型。它会很好地优化。
但是,如果您尝试实现类型相关的,与顺序无关的数组方法,例如reverse()
,您也可能会发现自己的实现更快。至少是我的。
为什么?
现在JavaScript经过了大量优化,特别是在相同类型的东西上循环和重复操作 - 数字,字符串,甚至相同形状的对象(它很复杂)。在极端情况下,运行时将内联您的函数,将跳过变量类型检查,并且在Chrome的情况下,甚至会将您的数字保存在注册表中,以便您的循环可以像C一样快。
哇。
但近年来这些优化措施才刚刚起步。目前,本机功能尚不像用户代码那样可以优化。它们没有像用户代码那样进行过多的动态优化。
在那里,我说了。
目前,用户代码可能比本机实现运行得更快,特别是因为程序员知道其中的数据流。但这可能是暂时的。
我会在这里停下来让你决定是否要创建自己的数组库。 ;)
答案 2 :(得分:0)
这是一个非常疯狂的猜测,但是由于本机排序可能会导致性能下降,检查传递的属性是空白还是空...因此在每次搜索时搜索默认函数(而不是一次)... 。
这可能是一个错误的优化问题,如果真的可以解决...希望firefox开发人员可以回答这个问题:)