优化JavaScript循环确实是必要的吗? [英] Is optimizing JavaScript for loops really necessary?

查看:119
本文介绍了优化JavaScript循环确实是必要的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读到,建议通过 读取循环头文件中每个迭代的数组的长度属性。



所以,我们应该这样做: p>

  var names = ['George','Ringo','Paul','John']; 
for(var i = 0,j = names.length; i< j; i ++){//读取数组长度一次,并将其赋值给一个变量
doSomeThingWith(names [i]);

$ / code $ / pre

而不是这个:

  var names = ['George','Ringo','Paul','John']; 
for(var i = 0; i< names.length; i ++){
doSomeThingWith(names [i]);
}

然而,我创建了一个小的测试用例来比较这两种技术,但有时候第一种情况会更快,有时会比第二种更快。



你推荐哪个版本? 首先,我应该说这个答案是在2011年编写的,随着时间的推移,这些事情会发生变化(因为浏览器解释器会优化越来越多的东西),所以如果你真的想知道当前的世界状态,你必须在当前的浏览器上运行测试。 b

在任何版本的IE上运行自己的jsperf测试。在那里你会看到两种方法或许多其他旧浏览器之间的一致性差异。你显然只在Chrome浏览器上运行它,这是如此之快,如此优化,这两种方法之间的差异可以忽略不计。在IE9(这可能比IE7和IE8更好),预缓存长度的方法是31%的速度。



为这个问题设计的jsperf测试给出了这个问题的定量结果。在这样的问题中,我们应该去看看真正的区别是什么,而不是那么多的猜测。

它显示了我尝试的浏览器的差异,从几乎没有区别到取决于浏览器的相当大的差异。在Chrome中,几乎没有区别。在IE9中,首先存储的长度快了将近50%。 现在,这个速度差异是否与您的脚本有关取决于具体情况码。如果你有一个巨大的数组,你经常循环,它可以在一些浏览器使用这种形式有意义的区别:

  for(var i = 0,len = list.length; i< len; i ++){
//在这里做代码
}

略微不同的测试用例,当使用一些DOM函数返回的真正的虚拟数组时,速度依然存在差异,但是没有放大(我预计DOM伪直播数组的差异会更大,但是不是这样) 。

在实践中,我倾向于使用短版本(少打字),当我不认为我的代码段速度至关重要和/或数组不是大,如果我有意识地考虑速度或数组是巨大的,或者我在同一个数组上做了很多迭代,我会使用预缓存长度的较长版本。



有一个co由于其他编程原因,预先缓存长度。如果要在循环中将元素添加到数组的末尾,并且不希望循环遍历这些新添加的元素,那么您将需要预加载该长度,并仅迭代最初存在的元素。

pre $ for(var i = 0,len = list.length; i< len; i ++){
if(list [i] ==whatever){
list.push(something);




$ b $ p
$ b

请记住,浏览器正在不断发展和增加更多和更多的优化,所以在2011年显示出巨大收益的优化可能基本上被构建到更现代的浏览器中,因此不再需要手工编码优化。所以,如果你想为今天的表现优化一些东西,那么你必须在今天的浏览器上进行测试,而不能只依赖你阅读过的几年前的东西。

I read that it is advised to optimize loops in JavaScript by not reading the length attribute of an array every iteration in the loop header.

So, we should rather do this:

var names = ['George','Ringo','Paul','John'];
for(var i=0,j=names.length;i<j;i++){// Read array length once and assign it to a variable
    doSomeThingWith(names[i]);
}

instead of this:

var names = ['George','Ringo','Paul','John'];
for(var i=0;i<names.length;i++){
    doSomeThingWith(names[i]);
}

However, I created a small testcase to compare the two techniques, but sometimes the first case was faster and sometimes the second one.

Which version would you recommend?

解决方案

First, I should say that this answer is written in 2011 and these things change over time (as browser interpreters optimize more and more things) so if you really want to know the current state of the world, you have to run tests on current browsers.

Run your own jsperf test on any version of IE. There you will see a consistent difference between the two methods or many other old browsers. You apparently only ran it on Chrome which is so fast and so optimized that there is a negligible difference between the two methods. On IE9 (which is likely way better than IE7 and IE8), the method which pre-caches the length is 31% faster.

A jsperf test designed for this question gives quantitative results on this question. In questions like this one should just go to jsperf to see what the real difference is rather than so much speculation.

It shows a difference in the browsers I tried that ranges from almost no difference to a pretty sizable difference depending upon the browser. In Chrome, there's almost no difference. In IE9, storing the length first is almost 50% faster.

Now, whether this speed difference matters to your scripts depends on the specific code. If you had a huge array that you were looping through frequently, it could make a meaningful difference in some browsers to use this form:

for (var i = 0, len = list.length; i < len; i++) {
    // do code here
} 

In a slightly different test case when using live pseudo arrays returned by some DOM functions, there was still a difference in speed, but not as magnified (I expected the difference to be greater on DOM pseudo live arrays, but it wasn't).

In practice, I tend to use the short version (less typing) when I don't think my section of code is speed critical and/or the array is not large and I would use the longer version that pre-caches the length if I am consciously thinking about speed or the array is huge or I'm doing a lot of iterations over the same array.

There are a couple other programming reasons to pre-cache the length. If you will be adding elements to the end of the array during the loop and you don't want to the loop to iterate over those newly added elements, then you will NEED to pre-load the length and only iterate over the initially present elements.

for (var i = 0, len = list.length; i < len; i++) {
    if (list[i] == "whatever") {
        list.push("something");
    }
} 

Keep in mind that browsers are continually evolving and adding more and more optimizations so an optimization that shows great benefit in 2011 may be essentially built into a more modern browser in the future so the hand coded optimization is no longer needed. So, if you're trying to optimize something for today's performance, you have to test in today's browsers, you can't just rely on things you read that may be a few years old.

这篇关于优化JavaScript循环确实是必要的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆