JavaScript,使用第二个参数排序更快

时间:2011-08-28 12:51:12

标签: javascript performance sorting

我做了一点测试,发现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);
}

3 个答案:

答案 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开发人员可以回答这个问题:)

相关问题