5

我正在玩一些 javascript 性能优化,发现了一些有趣的东西。这是代码:

function gObject() {

    this.obj = [];
    this.LIMIT = 100000;

    this.doLoopLocal = function () {
        var o = [];
        for (var i=0;i<this.LIMIT;i+=1) {
            o.push(i);
        }
        return o;
    };      

    this.doLoopObject = function () {
        this.obj = [];
        for (var i=0;i<this.LIMIT;i+=1) {
            this.obj.push(i);
        }
    };
};

var g = new gObject();

console.time('Using Local array');
g.doLoopLocal();
console.timeEnd('Using Local array');

console.time('Using Object array');
g.doLoopObject();
console.timeEnd('Using Object array');

当我运行它时,日志告诉我使用本地数组比使用对象命名空间中定义的数组慢。差异是显着的 - 8 到 10 倍!(FF 18.0.1)

Using Local array: 16ms
Using Object array: 2ms

截图:在此处输入图像描述

我一直假设在函数中使用本地定义的对象更快,但这个实验表明我错了。为什么会发生这种情况?

更新:我在本地 Firefox 控制台中尝试了该脚本,并且数字是我最初所期望的:使用本地数组优于使用对象数组。所以真正的原因是 Firebug 出于某种原因扭曲了数字并显示了不正确的结果。要记住的事情。

4

1 回答 1

1

与魔法一样,魔法在于相信它正在发生的眼睛。
顺便问一下,你在这里测试什么?如果我们忘记了,在你的 doLoopObject 中,你没有返回 this.obj,只是测试几次表明结果是“随机的”,更糟糕的是:如果你颠倒测试的顺序,它们可能会根据浏览器而改变。结果将取决于您在两次点击之间等待的时间。如果您等待几秒钟,它们将始终几乎相等。
现在请注意,在 JSPerf 上,数字增长的速度,特别是在 Firefox 上,解释变得非常明显:有周期性的减速:垃圾收集器是由此类垃圾创建函数触发的。当它触发时,数字会增加得更慢,可能是一个对象或一个本地变量(没关系)。您在这里测量的是垃圾收集器时间,而不是对象属性与局部变量相比的 push() 时间。这就解释了为什么顺序和测试之间的时间会改变事情。
我要补充一点,两次测试之间的变化太大,无法得出任何结论。

但最重要的是,当等待的时间足够长时,两个测试在 FF/Safari 上的表现都是一样的......

您可以从所有这些中得出的唯一结论是:两种方法的执行方式相同。

但是由于任何分配这么多“堆”的人无论如何都会立即分配,使用简单的 myArray[lastIndex-1]=0,恐怕真正的结论是:这个测试什么也没显示。

于 2013-02-10T17:23:27.337 回答