我正在为一个项目开发一些快速循环,我决定进行一个简单的测试,以比较运行一个更复杂的内部循环与运行几个简单的内部循环时性能的变化。下面是它的jsperf:
http://jsperf.com/nested-fors-vs-iterative-fors我很惊讶这种差异是如此显著。
谁能指出为什么我的测试很糟糕(很可能是这样),或者解释为什么性能差异。
谢谢!
idb
我不知道为什么你需要underscore.js和jQuery。我已经编写了一个非库版本,比较:
- 100次循环,每10次循环1次呼叫(1000次呼叫)
- 100次循环10次呼叫(1000次呼叫)
- 200次循环5次呼叫(1000次呼叫)
- 1次呼叫1000次循环(1000次呼叫)
两者的性能非常相似。
我认为你的问题是第一种情况是100个匿名函数,每个函数调用10次。第二个是1000个匿名函数,每个函数调用一次。开销可能是在创建匿名函数时产生的(尽管我还没有看到正在使用的库的相关内部部分)。
在第一种情况下,您将一个迭代器函数调用100次。在第二种情况下,将10个迭代器函数调用100次。这是函数调用次数的10倍。我想说开销是造成差异的原因。
我认为你的测试有一个苹果到橙子的问题——在你的第一个测试中,你循环了整数数组1 * 100
次,总共执行了100次函数(执行了你的doSomething
函数10次,总共执行了1000次)
第二个case在整数数组10 * 100
上循环了1000次,总共执行了10个匿名函数,每个函数调用doSomething
函数一次。对一个包含100个元素的数组遍历10次要比遍历一次花费更多的时间。创建10个匿名函数,每个函数调用100次,绝对比创建一个匿名函数,调用100次要多。这两件事结合起来会使你的测试完全不同。
试试这个:
function doSomething(a) {
a * 10 + a * 1000000.0 / 50.0;
}
var range = _.range(100),
total_runs = _.range(10);
_.each(total_runs, function(a) {
_.each(range, doSomething);
});