今天有人问到如何优化一段js代码,我看到他用的是简单的<code>for(;;),我随口说了使用for(in)来优化,因为我觉得for(in)看起来比较短,他觉得不是,他说他以前看过文章,说for(in)的效率低下,于是我作了如下一个测试。
这是for(in)的代码:
var arr=new Array(1000); var d=new Date(); for (var i=0;i < 100;i++){ for (a in arr){;} } alert(new Date()-d);
这是for(;;)的代码:
var arr=new Array(1000); var d=new Date(); for (var i=0;i < 100;i++){ for (var a=0;a < arr .length;a++){;} } alert(new Date()-d);
结果令我大吃一惊,for(in)耗时居然为0,而for(;;)却总是无法完成任务…,难道for(in)的效率奇高吗?不可能吧?
我的第一感觉就是for(in)对空数组(数组内容是undefined)感冒,会跳过去,后来作的另一个测试证明了这一点:
var arr=[true,,false,true]; for (a in arr){alert(a)}
这个测试的结果就是数组的第二个元素(为空)会被跳过去。。
在证明了这一点之后,我将程序改为如下:
var arr=new Array(100).join(".;.").split(";"); var d=new Date(); for (var i=0;i < 100;i++){ for (var a=0;a < arr .length;a++){;} } alert(new Date()-d); d=new Date(); for (var i=0;i < 100;i++){ for (a in arr){;} } alert(new Date()-d);
测试结果证实了网友的说法,for(in)的效率极低,已经不是一个数量级的差距,是10几倍的差距。接下来,我继续深入作了一个测试,把我知道的几种遍历方式都进行了一次比较:
var arr=new Array(1000).join(".;.").split(";"); var d=new Date(); for (var i=0;i < 100;i++){ for (var a=0;a < arr .length;a++){;} } alert("for(;;)="+(new Date()-d)); d=new Date(); for (var i=0;i < 100;i++){ for (a in arr){;} } alert("for(in)="+(new Date()-d)); d=new Date(); for (var i=0;i < 100;i++){ for (var a=0,c;c=arr[a];a++){;} } alert("for(a,c;;)="+(new Date()-d)); d=new Date(); for (var i=0;i < 100;i++){ var a=0; while(arr[a++]){;} } alert("while()="+(new Date()-d));
测试结果是(由快到慢):for(;;)<while ()<for(a,c)<for(in),前面几个的差距在小数量级的循环下可以接受,而for(in)所消耗的时间实在是不敢恭维。。。
其中,for(a,c)是我的教训。。。我在没有进行任何对比测试的时候,就偏信网上某贴上的评论,认为它的速度比for(;;)还快。。。唉。。。
最后,再测试一下多一个变量是否会进一步提升for(;;)的速度。
var arr=new Array(1000).join(".;.").split(";"); var d=new Date(); for (var i=0;i < 1000;i++){ for (var a=0;a < arr .length;a++){;} } alert("for(;;)="+(new Date()-d)); d=new Date(); var l=arr.length; for (var i=0;i < 1000;i++){ for (var a=0;a < l;a++){;} } alert("for(;l;)="+(new Date()-d));
还是有满明显的效率提升滴~~点击下面这个按钮实际查看它们的运算速度:


