A JavaScript Fancier

伟大的javascript技术研究中...

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  304 随笔 :: 0 文章 :: 479 评论 :: 0 Trackbacks


循环作为程序语言的三大逻辑控制结构之一,在实际开发是经常会遇到的。
在JavaScript程序的循环结构使用上,我们经常会遇到这种应用。
根据一个对象的长度进行循环并对对象每个每个元素进行处理。

for(var i=0;i<a.length;i++){
    sum
+=a[i]
}

以上只是一个简单的示例,对于如上程序,很多程序开发者都研究过关于其执行效率的问题。
因此就出现了以下的两种写法:
for(var i=0,iLen=a.length;i<iLen;i++){
    sum
+=a[i]
}

for(var i=0,item;item=a[i];i++){
    sum
+=item;
}

for(var i=0,item;(item=a[i])!=undefined;i++){
    sum
+=item;
}


对于三种写法其性能到底有多大差异呢?到底哪个的效率更高呢?

我在自己的机器上对其做了测试:
发现在10000条数据以下时三者执行速度差别不大,差别大概在0.01m左右,而且测试结果不稳定。
然后将数据变为50w条进行测试:
三种方法测试结果分别为:
1182
981
1673(而且出现“程序执行缓慢,是否取消该脚本”的提示)

1572
1462
12067(同样出现了脚本加载缓慢的提示)

尽管数据并不是非常稳定,但还是能从中发现点什么的。

速度最快的是第二种写法:即保存对象长度,避免每次都计算
速度最慢的是第三种写法:即不关系对象的长度,而根据当前项是否存在来循环。

之前我一直以为是第三种写法速度应该是最快的(因为不用计算长度),今日一测才发现第三种的执行效率如此低下,看来还是避免使用。当然,很多时候我们可能还是不得不使用这第三种写法。

测试程序如下:(建议分开对三个程序进行测试,特别是在FF下)
<script type="text/javascript">
  
<!--
  
var a=[];
  
for(var i=0;i<500000;i++){
    a.push(
100);
  }
  
var sum=0;
  
var timer1=new Date().getTime();
  
for(var i=0;i<a.length;i++){
    sum
+=a[i];
  }
  alert(sum
+"\ntime:"+(new Date().getTime()-timer1));

  sum
=0;
  
var timer2=new Date().getTime();
  
for(var i=0,iLen=a.length;i<iLen;i++){
    sum
+=a[i];
  }
  alert(sum
+"\ntime:"+(new Date().getTime()-timer2));

  sum
=0;
  
var timer3=new Date().getTime();
  
for(var i=0,item;item=a[i];i++){
    sum
+=item;
  }
  alert(sum
+"\ntime:"+(new Date().getTime()-timer3));
  
//-->
  </script>

posted on 2007-12-18 23:47 Yemoo'S JS Blog 阅读(2383) 评论(4)  编辑 收藏 引用 所属分类: javascript技巧总结

评论

# re: 三种For循环写法的性能比较 2007-12-20 16:30 CoffeeCat
恩,写的挺好的!
length是数组中的属性,所以它的访问速度和访问变量是一样的,第1种方法比第2种方法慢就慢在对象访问,也就是a.这个操作,不过性能不会差很多。
第3种方法我觉得主要是慢在item=a[i],这是一个赋值语句,它的性能肯定要比比较语句慢得多。您可以试试以下程序,也就是去掉赋值操作,看看性能是不是符合您的预期?

for(var i=0;a[i];i++){
sum+=a[i];
}

我测试了一下,貌似依然是最慢的,看来还是慢在Javascript的判断对象是否是undefined的操作上。
我还测试了一下执行1次
a[i];a[i];
要比执行1次
item=a[i];item;
稍微快一点~
  回复  更多评论
  

# re: 三种For循环写法的性能比较 2008-06-07 23:19 BIDAAS
@CoffeeCat
JS是弱类型语言但并不意味着它没有类型,执行引擎最终会进行类型转换并运算,在for(var i=0;a[i];i++)判断的时候,这里会进行数据类型判断、类型安全判断,然后类型转换,最终变成我们期望的bool值,其实这在我们看来一句话的过程,执行引擎却会执行N多判断的代码,效率能高吗?这是一点。
其次,访问lenght属性的效率肯定比变量要慢N多。要注意的是,这里的lenght属性的实现并非你想像的那么简单,它的实现就是1个无参数的get方法,并且返回int值。你试想一下,就算是一个简单的函数,就只执行return 操作,也比访问变量要慢N多,因为return操作开辟一个新的内存空间来保存返回值,而接受返回值的变量又要开辟新内存空间来保存这个返回过来的值  回复  更多评论
  

# re: 三种For循环写法的性能比较 2009-03-31 11:16 penrcz
我以前也是一直以为是第三种写法速度应该是最快的

呵呵...谢谢您...我以后少用这种for  回复  更多评论
  

# re: 三种For循环写法的性能比较 2010-11-24 15:14 itworktor
貌似国外早就有牛人搞出更牛逼的方式,比如说展开循环之类的方式。  回复  更多评论
  

只有注册用户登录后才能发表评论。