循环条件缓存的Javascript
我已经完成了一个jsperf测试,它比较了在数组上迭代时缓存数组长度条件与不缓存的循环。我认为在每次迭代之前缓存变量以避免重新计算数组长度会更快,但jsperf测试则相反。有人能解释为什么会这样吗?我还认为在for循环的初始化中包含数组长度变量定义(缓存时)会减少时间,因为解析不需要两次查找“var”关键字,但情况似乎并非如此 不带缓存的示例:循环条件缓存的Javascript,javascript,performance,Javascript,Performance,我已经完成了一个jsperf测试,它比较了在数组上迭代时缓存数组长度条件与不缓存的循环。我认为在每次迭代之前缓存变量以避免重新计算数组长度会更快,但jsperf测试则相反。有人能解释为什么会这样吗?我还认为在for循环的初始化中包含数组长度变量定义(缓存时)会减少时间,因为解析不需要两次查找“var”关键字,但情况似乎并非如此 不带缓存的示例: for(var i = 0; i < testArray.length; i++){ // } for(变量i=0;i
for(var i = 0; i < testArray.length; i++){
//
}
for(变量i=0;i
缓存示例
var len = testArray.length;
for(var i = 0; i < len; i++){
//
}
var len=testArray.length;
对于(变量i=0;i
在for循环初始化中定义了缓存变量的示例
for(var i = 0, len=testArray.length; i < len; i++){
//
}
for(变量i=0,len=testArray.length;i
有人能解释为什么会这样吗
这种优化和案例非常常见,因此现代JavaScript引擎将自动为您执行这种优化
一些注意事项:
- 迭代节点列表(例如
querySelectorAll
- 无论如何,对于大多数代码路径来说,这是一个过度的微优化,通常循环体比这个比较花费更多的时间
- 迭代节点列表(例如
querySelectorAll
- 无论如何,对于大多数代码路径来说,这是一个过度的微优化,通常循环体比这个比较花费更多的时间
如果有一个完美的优化器,这三个示例的性能应该是相同的。由于您的示例非常简单,现代引擎应该很快达到这一点。您发布的场景的性能取决于JS引擎的优化器有多聪明。一个具有非常转储优化器(或者根本没有优化器)的引擎当您使用变量时,速度可能会更快,但您甚至不能依赖于此。毕竟,length的类型是众所周知的,而变量可以是任何类型,并且可能需要额外的检查。
如果有一个完美的优化器,所有三个示例都应该具有相同的性能。由于您的示例非常简单,现代引擎应该很快达到这一点。长度实际上不是在访问时计算的,而是在数组发生变化时更新的静态值。今天的引擎可能会为
de>循环。在您的jsperf示例中,Console.Log可能不是循环主体中最好的东西。去掉Console.Log
:性能基本相同。正如其他人所说,这可能已经由浏览器优化了。访问时,实际上不会计算长度的可能重复,这是一个静态变量当数组发生变化时更新的lue。今天的引擎可能会为
循环优化正常的。在您的jsperf示例中,Console.Log可能不是循环体中最好的东西。摆脱Console.Log
:性能基本相同。正如其他人所说,这可能已经由浏览器。可能是+1:50000的副本控制台。log
这是OPs测试中的瓶颈,不是两个数字的比较。是的,这只是一个随意的循环,我没有意识到它会产生这样的影响。感谢更新jsperf@ejfrancis对代码进行基准测试是很困难的,而且要在微型计算机中正确地完成它chmark更难。即使在那之后,你也不确定它是否有意义。+1:50000console.log
这是OPs测试中的瓶颈,不是两个数字的比较。是的,这只是一个随意的循环,我没有意识到它会产生如此大的影响。感谢更新jsperf@ejfrancis基准编写代码是很难的,而在微基准测试中正确地完成代码则更难。即使在这之后,你也不确定它是否有意义。