Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

with语句是JavaScript的性能杀手

  本来想直接翻V8的代码出来看看实现原理,但是V8的代码实在太乱了,凤毛麟角的优化代码太多,可读性差,所以就只能做个实验测试咯。这里测试三种情况: //情况1:普通的循环
(function(){
  var i,t;
  t=new Date;
  for(i=0;i<1E6;i++);
  document.write(new Date-t,"<br/>");
})();
//情况2:同作用域下存在with的循环
(function(){
  var i,t;
  t=new Date;
  for(i=0;i<1E6;i++);
  document.write(new Date-t,"<br/>");
  with({});
})();
//情况3:with作用域下的循环
(function(){
  var i,t;
  t=new Date;
  with({})for(i=0;i<1E6;i++);
  document.write(new Date-t,"<br/>");
})();

  在IE和Opera中遇到情况2采取了无视它的措施。而FireFox和Chrome中只要with存在作用域下都会影响到变量的访问效率。Chrome的影响不算大,也就几倍而已。FireFox中直接坑爹!情况3的结果就是预料中之中的了,with作用域下的变量访问效率和原来差了好多。这也是匪夷所思的地方,为什么会差这么多呢?with只不过是在访问变量的时候,优先在with指定的对象中查找它的属性而已。上面情况3中的with下面是个for循环,也就是说每一轮循环i会被访问到两次。那么我们模拟的做一下。 var i,t,o={};
t=new Date;
for(i=0;i<1E6;i++){
  //判断o中是否有i这个属性两次
  if("i" in o);
  if("i" in o);
};
document.write(new Date-t,"<br/>");

  感觉很诡异吧,IE下使用with的效率都比判断两次in的效率高。我觉得IE中的实现应该是有VB的前车之鉴,所以会做的好一些。Opera很大一部分是参考IE的,从最初的document.all就能看出,所以我猜它们的实现应该很相似。而FireFox和Chrome就比较现代化,他俩会比较相似。不过从代码上分析也只能到此为止了。根据我的猜测Chrome和FireFox中是把with作为一个Scope来处理,所以慢;而IE和Opera中应该是像我上面的第二个例子中那样判断的所以快。还有更为诡异的上面测试代码中的情况2,FireFox和Chrome上,存在with的作用域的变量访问效率会变低,这个原因就很复杂了。我猜是它们为了实现这个with,做了一些破坏当前作用域数据结构的事情,所以把整个作用域的效率都拉下来了。
  这样一味的猜测也不是办法,我还是乖乖的研究具体的实现过程去。不过对于实际开发来说,弃用with就好。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^