3

我已经实现了一个简单的轻量级every功能。我注意到,如果该变量arguments以某种方式在函数内部使用——它会将运行时间从800 毫秒增加到1300 毫秒(在我的情况下)。这是什么原因造成的?

我使用Chrome 29.0.1547.66 m

http://jsfiddle.net/4znzy/

function myEvery(list, fun, withArgument) {
    var i;

    fun = fun || function(val) { return val };

    arguments; // with this statement the time is 1300 ms
               // if you comment it out -- 800 ms

    for (i = 0; i < list.length; i++) {
      if (!fun.call(list, list[i], i)) {
        return false;
      }
    }

    return true;
};

// Create a huge array
var list = [];
for (i = 1; i < 20000000; i++) {
    list.push(i);
}

// Measure the time
t1 = (new Date).getTime();
myEvery(list);
t2 = (new Date).getTime();

alert(t2 - t1);

(如果要测量执行arguments语句本身的时间,则为 0 ms。)

4

1 回答 1

1

的外观arguments就像函数参数的动态 getter,必须从堆栈中读取 - 并被复制。像您的参数这样的大对象(不仅是大对象,还有很多对象)list也必须被复制

您可以通过将arguments行替换为

var args = [list.slice(0)]; // copy parameter

这导致相似的时间。我的机器上还有 150arguments个和 200 个。slice()

根据 JS 引擎的实现,这会更慢或更快,但肯定会增加执行时间。不同浏览器或替代 JS 引擎之间可能存在(尚未测试)相当大的差异。

于 2013-09-06T06:27:18.890 回答