Web 技术研究所

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

原型链的效率问题

  上一篇既然纠正了原型链的认知,那这篇就趁热打铁。来试试原型链的效率吧!由于没有标准对实现方式的约束,在各个引擎下使用的实现方式都不同,这就带来了各种兼容性问题和效率差异。虽然我们对原型链的概念很清晰了,但是对于效率还是得从长计议。
  根据原型链的概念,当我们访问一个对象的属性时候,如果对象本身不具有那个属性就会去上一级的原型中找,直到Object的原型为止。这就隐含了一个问题,如果一个原型链很长,对象的属性访问速度是不是也非常低呢?于是,我们创建一个很长的原型链来测试它属性的访问效率 var i,t,o,f,n;
//构造10000级原型继承
window["f0"]=function(){};
window["f0"].prototype.name="次碳酸钴";
for(i=1,n=1E4;i<=n;i++){
  f=window["f"+i]=function(){};
  f.prototype=new window["f"+(i-1)];
  f.prototype.constructor=window["f"+(i-1)];
};
//测试顶层实例对底层属性的访问速度
o=new window["f"+n];
t=new Date;
for(i=0;i<1E5;i++)o.name;
console.log(new Date()-t);
//测试直接从顶层访问的速度
o.name=null;
t=new Date;
for(i=0;i<1E5;i++)o.name;
console.log(new Date()-t);

  这个测试是创建一个有一万级的原型链,然后分别测试顶层访问和底层访问十万次的用时。Chrome下顶层属性和底层属性的访问效率要慢上千倍,火狐也差上几十倍,只有IE的效率最高。其实看到这个结果我一点都不惊讶,因为这个测试只针对一个属性,这样就有可能被引擎的缓存机制优化掉。以前很多测试都遇到过这样的问题,于是我们修改下测试代码,每次访问不同的属性。不能再做十万次测试了,那个时间太久,这回只做一千次测试。
var i,t,o,f,n=1E4,m=1E3;
//构造10000级原型继承
window["f0"]=function(){};
for(i=1;i<=n;i++){
  f=window["f"+i]=function(){};
  f.prototype=new window["f"+(i-1)];
  f.prototype.constructor=window["f"+(i-1)];
};
//写满数据
for(i=0;i<m;i++)window["f0"].prototype[i]=i;
//测试顶层实例对底层属性的访问速度
o=new window["f"+n];
t=new Date;
for(i=0;i<m;i++)o[i];
console.log(new Date()-t);
//写满数据
for(i=0;i<m;i++)o[i]=i;
//测试直接从顶层访问的速度
t=new Date;
for(i=0;i<m;i++)o[i];
console.log(new Date()-t);

  这个测试结果就直观的多了。如果属性在顶层,那么一千次访问在一毫秒之内就可以完成。如果属性在底层(一万次继承),那么访问所消耗的时间就要多的多。原型链就如同链表,每次访问需要遍历,时间复杂度为O(n)。所以原型链条越深需要的时间就越多。这东西就是这样,至于如何优化那就得看具体的项目需求了。
  
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^