使用prototype特性编程中的效率问题

简介:

    前几天有位网友询问了我一个问题,主要是关于JavaScript的prototype特性的效率。因为作为一个如此强大并且灵活的东西,难免会让人觉得效率上可能有较大的损失。但是实际上prototype特性的效率怎么样呢?我们下面来详细说说这个问题。

    之前我曾经写过两篇随笔介绍JavaScript语言的prototype特性,"JScript中的prototype(原型)属性研究(1)"和"JScript中的prototype(原型)属性研究(2)"。第一篇非常基础,只是说明了prototype的用途和用法,第二篇基本上算是深入说明了JavaScript的prototype的实现机制,不过当时没有对prototype的效率作任何讨论,真是遗憾。

    先看一个prototype属性和方法效率比较的示例:

None.gif < html >
None.gif < head >
None.gif     < title >Prototype Performancetitle>
None.gif     < meta  name ="author"  content ="birdshome@cnblogs"   />
None.gif </ head >
None.gif < body >
ExpandedBlockStart.gif ContractedBlock.gif     < script  language ="javascript" > dot.gif
InBlock.gif    
function  fnMethod(i)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif {
InBlock.gif        
var  tmp  =  i + 3 ;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    Object.prototype.i 
=   0 ;
InBlock.gif    Object.prototype.fnMethod 
=   function ()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif {
InBlock.gif        
var  tmp  =   this .i + 3 ;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif    
</ script >
ExpandedBlockStart.gif ContractedBlock.gif     < script  language ="javascript" > dot.gif
InBlock.gif    
function  Test_fnMethod()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif {
InBlock.gif        
var  dt  =   new  Date();
InBlock.gif        
for  (  var  i = 0  ; i  <   100  ;  ++ i )
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif {
InBlock.gif            
for  (  var  j = 0  ; j  <   10000  ;  ++ j )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                fnMethod(i);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        alert(
new  Date()  -  dt);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
function  Test_prototype_fnMethod()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif        
var  obj  =   dot.gif {} ;
InBlock.gif        
var  dt  =   new  Date();
InBlock.gif        
for  (  var  i = 0  ; i  <   100  ;  ++ i )
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif {
InBlock.gif            
for  (  var  j = 0  ; j  <   10000  ;  ++ j )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                obj.fnMethod();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        alert(
new  Date()  -  dt);
ExpandedSubBlockEnd.gif    }
    
ExpandedBlockEnd.gif    
</ script >
None.gif     < button  onclick ="Test_fnMethod()" >
None.gif        fnMethod </ button >
None.gif     < button  onclick ="Test_prototype_fnMethod()" >
None.gif        prototype.fnMethod </ button >
None.gif </ body >
None.gif </ html >

    上面示例的测试结果分别是:4,046ms和4,719ms!(P4 2.4G IE6 SV1 en)。普通方法和原型方法之间的每一次调用效率差别为:663/1,000,000 毫秒(实际上是一次原型属性和一次原型方法调用共同消耗的时间周期,var tmp = this.i+3;)。

    这个结果看起来挺不错的,似乎使用prototype也就不存在什么效率问题了。但是如果我们在一个页面中使用了大量的自定义对象,同时对象又和表现层的HTML元素对象建立了较密切的引用联系后,我们常常会觉的整个页面对脚本的执行都慢了下来,这是怎么回事呢?是谁在吞噬CPU资源?!

    这是由于JavaScript这种脚本语言不需要用户管理内存使用,所以它自身需要管理自己的资源开销,也就是说JavaScript的运行引擎要负责GC。但是JavaScript使用的"简单标记清除"算法,对于复杂的环状引用的标记不是很有效(我在IE的Memory Leak相关文章中有详细介绍),加之IE对于DHTML DOM象生存期策略等问题。当页面内的DOM和脚本对象越来越多,并不能及时释放后,IE的脚本执行效率就非常明显的降下来了。严重到我们刚打开IE时很简单的一个脚本操作,都会变得很缓慢,一执行CPU就会串到一个很高的占用峰值。


本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。

目录
相关文章
|
5月前
|
XML JSON 前端开发
前端深浅拷贝各有哪些方法,优缺点
前端深浅拷贝各有哪些方法,优缺点
43 0
|
8月前
|
存储 缓存 JavaScript
闭包的概念?优缺点?使用场景?
闭包的概念?优缺点?使用场景?
|
4天前
|
IDE Java 开发工具
讨论 Python 中泛型(或类似泛型的功能)的优点和缺点
Python虽无显式泛型系统,但可通过类型注解和工具实现类似功能。优点包括提升代码可读性、静态类型检查、更好的IDE支持、灵活性和可逐渐引入。缺点涉及运行时性能开销、学习成本、非强制性及与旧代码集成问题。适当使用工具和实践可管理这些挑战。
15 2
|
2月前
|
设计模式 定位技术 数据库
C++ 原型模式探秘:轻松复制对象的高效解决方案
C++ 原型模式探秘:轻松复制对象的高效解决方案
46 0
|
3月前
|
前端开发 JavaScript API
|
4月前
|
前端开发 JavaScript 算法
可维护的代码,高复用性之路:函数式编程带你飞(二)
可维护的代码,高复用性之路:函数式编程带你飞
|
4月前
|
机器学习/深度学习 人工智能 分布式计算
可维护的代码,高复用性之路:函数式编程带你飞(一)
可维护的代码,高复用性之路:函数式编程带你飞
|
5月前
|
缓存 JavaScript
巧用 computed 计算属性,实现代码简洁高效
巧用 computed 计算属性,实现代码简洁高效
98 1
|
6月前
|
缓存 Java 编译器
探究Java方法的优化与最佳实践:提升性能与代码可维护性
探究Java方法的优化与最佳实践:提升性能与代码可维护性
|
9月前
|
存储 算法 Java
探索Java数组:基础、特性与灵活应用
在Java编程中,数组是一种基础而重要的数据结构,它能够以紧凑的方式存储多个元素。无论是在简单的数据存储还是复杂的算法实现中,数组都扮演着不可或缺的角色。本文将引导您深入了解Java数组,包括数组的基本概念、特性、用法以及常见应用场景。