真理不是一种铸币,现成的摆在那里,可以拿来藏在衣袋里。 —— 莱辛

日记列表


  • 天气
  • 2006年07月05日 11:03 星期三

循环的效率

今天有人问到如何优化一段js代码,我看到他用的是简单的for(;;),我随口说了使用for(in)来优化,因为我觉得for(in)看起来比较短,他觉得不是,他说他以前看过文章,说for(in)的效率低下,于是我作了如下一个测试。

这是for(in)的代码:

Language:javascript, parsed in: 0.002 seconds, using GeSHi 1.0.7.12
  1. var arr=new Array(1000);
  2. var d=new Date();
  3. for (var i=0;i<100;i++){
  4.   for (a in arr){;}
  5. }
  6. alert(new Date()-d);
  7.  

这是for(;;)的代码:

Language:javascript, parsed in: 0.002 seconds, using GeSHi 1.0.7.12
  1. var arr=new Array(1000);
  2. var d=new Date();
  3. for (var i=0;i<100;i++){
  4.   for (var a=0;a<arr.length;a++){;}
  5. }
  6. alert(new Date()-d);
  7.  

结果令我大吃一惊,for(in)耗时居然为0,而for(;;)却总是无法完成任务...表情,难道for(in)的效率奇高吗?不可能吧?

我的第一感觉就是for(in)对空数组(数组内容是undefined)感冒,会跳过去,后来作的另一个测试证明了这一点:

Language:javascript, parsed in: 0.001 seconds, using GeSHi 1.0.7.12
  1. var arr=[true,,false,true];
  2. for (a in arr){alert(a)}
  3.  

这个测试的结果就是数组的第二个元素(为空)会被跳过去。。

在证明了这一点之后,我将程序改为如下:

Language:javascript, parsed in: 0.003 seconds, using GeSHi 1.0.7.12
  1. var arr=new Array(100).join(".;.").split(";");
  2. var d=new Date();
  3. for (var i=0;i<100;i++){
  4.   for (var a=0;a<arr.length;a++){;}
  5. }
  6. alert(new Date()-d);
  7. d=new Date();
  8. for (var i=0;i<100;i++){
  9.   for (a in arr){;}
  10. }
  11. alert(new Date()-d);
  12.  

测试结果证实了网友的说法,for(in)的效率极低,已经不是一个数量级的差距,是10几倍的差距表情。接下来,我继续深入作了一个测试,把我知道的几种遍历方式都进行了一次比较:

Language:javascript, parsed in: 0.006 seconds, using GeSHi 1.0.7.12
  1. var arr=new Array(1000).join(".;.").split(";");
  2. var d=new Date();
  3. for (var i=0;i<100;i++){
  4.   for (var a=0;a<arr.length;a++){;}
  5. }
  6. alert("for(;;)="+(new Date()-d));
  7. d=new Date();
  8. for (var i=0;i<100;i++){
  9.   for (a in arr){;}
  10. }
  11. alert("for(in)="+(new Date()-d));
  12. d=new Date();
  13. for (var i=0;i<100;i++){
  14.   for (var a=0,c;c=arr[a];a++){;}
  15. }
  16. alert("for(a,c;;)="+(new Date()-d));
  17. d=new Date();
  18. for (var i=0;i<100;i++){
  19.   var a=0;
  20.   while(arr[a++]){;}
  21. }
  22. alert("while()="+(new Date()-d));
  23.  

测试结果是(由快到慢):for(;;)

其中,for(a,c)是我的教训。。。我在没有进行任何对比测试的时候,就偏信网上某贴上的评论,认为它的速度比for(;;)还快。。。唉。。。

最后,再测试一下多一个变量是否会进一步提升for(;;)的速度。

Language:javascript, parsed in: 0.004 seconds, using GeSHi 1.0.7.12
  1. var arr=new Array(1000).join(".;.").split(";");
  2. var d=new Date();
  3. for (var i=0;i<1000;i++){
  4.   for (var a=0;a<arr.length;a++){;}
  5. }
  6. alert("for(;;)="+(new Date()-d));
  7. d=new Date();
  8. var l=arr.length;
  9. for (var i=0;i<1000;i++){
  10.   for (var a=0;a<l;a++){;}
  11. }
  12. alert("for(;l;)="+(new Date()-d));
  13.  

还是有满明显的效率提升滴~~点击下面这个按钮实际查看它们的运算速度:

昵称*:

邮箱 :

主页 :

  • :)
  • :o
  • :D
  • ;)
  • :p
  • :mad:
  • :confused:
  • :(
  • :rolleyes:
  • :cool:
  • :eek: