随笔-57  评论-129  文章-0  trackbacks-0
前几天无意中看到一个网友blog上关于这个循环效率的问题,说要尽量避免使用。
有点害怕,我在JSI中可是用了不少,呵呵。
测试一下,负担终于可以放下来了:

测试对象:
一个对象模拟map,测试for in 循环
两个数组,测试for(;;)循环

连续4次运行时间比。
957/1278;955/1357;1014/1282;968/1392


明显,要实现类似map的功能,还是for in 快点。

上面的数据是ff2上的结果,ie7上也差不多,差距更小一点。

测试代码:
function C(i){
  
return i<62?
    String.fromCharCode(i
+=
      i
<26?65
        :i
<52?71//97-26
          :-4//48-26-26
    )
      :i
<63?'_'
        :i
<64?'$'
          :C(i
>>6)+C(i&63)
}
var map = {};
var arr1 = [];
var arr2 = [];

for(var i = 0;i<1000;i++){
  
var c = C(i);
  map[c] 
= i;
  arr1.push(c);
  arr2.push(i);
}
var i = 0;
var mapTime = 0;
var arrTime = 0;
var inc = 0
while(inc++<500){
  
var t1 = new Date();
  
for(var n in map){
    n 
= map[n];
  }
  
var t2 = new Date();
  
for(var j = 0;j<1000;j++){
    n 
=arr1[j];
    n 
=arr2[j];
  }
  
var t3 = new Date();
  mapTime
+=(t2-t1);
  arrTime
+=(t3-t2);
}

prompt(
"mapTime/arrTime",mapTime +'/'+arrTime)


posted on 2007-05-27 17:18 金大为 阅读(1463) 评论(13)  编辑  收藏 所属分类: JavaScript

评论:
# re: 关于javascript for in 循环效率的疑惑 2007-05-27 17:26 | dreamstone
不错,很少研究js的效率。拜读。。  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-05-27 19:16 | 金大为
感觉JS这类脚本语言的效率不能拿一般的编译型语言去类推,差别较大。
解释型,特别是js这种比较慢的解释型语言,解释时间大于运行时间,所以,我们要记住一个原则,语句越少越好。能用原生的就不要自己写。
还有,js函数调用也是较大的开销,不太复杂的,效率要求苛刻的,能inline就不要函数了。  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-06-03 16:12 | emu
测试不够严谨:
在循环中重复了1500次new Date()操作,这个构造对象的代价算谁的?
每次new Date()后去相减后累加,这里每次得到的时间差有0~1/18.6秒的误差。这个误差在最后累加起来,结果是笔糊涂帐。
最后,如楼主在另一篇文章里面提到的,循环反转也会影响结果(受教了:P)

这样的一个对比应该是稍稍合理一点点的:

var n,m;
var inc = 0
var t1 = new Date();
while(inc++<500){
for(var n in map){
m = map[n];
}
}

var t2 = new Date();
inc=0;
while(inc++<500){
for(var j=arr1.length-1;j>=0;j--){
n =arr1[j];
m =arr2[j];
}
}
var t3 = new Date();
var mapTime=(t2-t1);
var arrTime=(t3-t2);


prompt("mapTime/arrTime",mapTime +'/'+arrTime)

但是事实上,两个循环仍在相互干扰,试试简单的把一个循环的数据构造和遍历都完整的去掉,另一个立刻就会体现出来不同:

function C(i){
return i<62?
String.fromCharCode(i+=
i<26?65
:i<52?71//97-26
:-4//48-26-26
)
:i<63?'_'
:i<64?'$'
:C(i>>6)+C(i&63)
}
var map = {};
//var arr1 = [];
//var arr2 = [];
var n,m;
for(var i = 0;i<1000;i++){
var c = C(i);
map[c] = i;
// arr1.push(c);
// arr2.push(i);
}
var inc = 0
var t1 = new Date();
while(inc++<500){
for(var n in map){
m = map[n];
}
}
var t2 = new Date();
/*
inc=0;
while(inc++<500){
for(var j=arr1.length-1;j>=0;j--){
n =arr1[j];
m =arr2[j];
}
}
*/
var t3 = new Date();
var mapTime=(t2-t1);
var arrTime=(t3-t2);


prompt("mapTime/arrTime",mapTime +'/'+arrTime)

  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-06-03 18:45 | 金大为
@emu
其实,我认为你的回复也不够严谨.
new Date的开销没错,但是基本可以忽略,而且没有偏向任何一方.

开销是均摊的.
就算你的浏览器new Date有点耗时,甚至取的时间不够准,这种误差,通过了多次测试来平衡.

不过,循环反转确实对效率有影响.
但是,循环反转只是对后者的,是否需要优化之后测试.也不知道那个更加公平,毕竟我们平时的编码,都懒得去反转.

更正:上次回复没有注意。
这里循环反转已经没有意义了。
for(var j = 0;j<1000;j++){
翻转的意义只在中间判断条件时用常量去判断,不用取变量甚至属性,而这里最大值已经是常量,反转也就完全没有意义了。
不知道你是这个例子没看清楚还是上个测试没看明白。  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-06-03 22:54 | emu
new Date并不是没有偏向任何一方,而是根本不知道偏向了哪一方。
开销的“均摊”导致了糊涂账。好比我和李嘉诚各花掉1万块,我们的财富比例绝对会发生质的变化,而不会“均摊”
在“多次测试”过程中间,每次都重新引入一次的误差,是无法通过增加测试次数来平衡的。
  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-06-04 08:19 | 金大为
@emu
也不知道你靠什么脑袋吃饭的,转不过弯来可以自己建个数学模型分析测试一下.
Date的开销不会改变时间的差距,不过,对比率确实有一点影响.
最后谁重谁轻是不会改变的.  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-06-04 09:34 | emu
偶并没有否定最后的结果,只是指出测试方式的不严谨而已。ok,偶是木头脑瓜,楼主不喜欢听不同意见,偶大可以不说。  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-06-04 17:48 | 金大为
@emu
有价值的不同意见,我非常感激,没有价值的意见,还是留个耳根清静的好。
  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-06-06 12:44 | hj
通过拜读楼主的几篇文章发现楼主是个很有个性的人  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-07-16 11:27 | jarry
我得试试,hoho  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-11-08 03:00 | 五彩阁
如何能避免两段JS代码想到干扰呢  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-11-08 21:32 | 金大为
@五彩阁
看JSI http://www.xidea.org/project/jsi
下一个版本的JSI将实现脚本的导出功能。
就是说,JSI只作为一个开发期的框架。

通过对脚本合并编译实现  回复  更多评论
  
# re: 关于javascript for in 循环效率的疑惑 2007-12-31 16:51 | java综合网
http://www.javazh.cn
不错,不错  回复  更多评论
  

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


网站导航: