网络编程
位置:首页>> 网络编程>> JavaScript>> JScript下Array对象的性能问题(5)

JScript下Array对象的性能问题(5)

作者:hax 来源:hax的技术部落格 发布时间:2009-02-15 12:28:00 

标签:jscript,array,数组,性能,对象

归根到底,既然是一个稀疏数组,则通常不会进行遍历,更没有理由执行 array.length = 0 之类的语句,如果要抛弃一个数组,直接 array = null 即可。

相反,普通(非稀疏)的数组,就是用来遍历的。因此很容易写出这样的代码:

while (array.length > 0) {   
  var e = array.pop()   
  // do sth for e   
}  

或者

while (array.length > 0) {   
  var e = array[array.length - 1]   
  // do sth for e   
  array.length--   

 所以我所能得出的结论是,JScript的Array.length的算法实现实在非常愚蠢。幼稚程度堪比我们诟病的白痴的垃圾回收策略

当然,比起垃圾到极点的垃圾回收算法给我们造成的麻烦,这个length的问题还是可以有workaround的,不必干等IE8那样复杂到狂出bug(见第一篇blog下面的comments)的设计。比如IE8 beta1的platform performance improvements白皮书里就提到,有人自己造轮子:

//user defined array type called 'prototypeArray'    
var prototypeArray = function() {    
  this._array = [];    
  this.length = 0;    
  this.start = 0;    
  this.end = 0;    
}   
//push method for user defined array type 'prototypeArray' prototypeArray.prototype.push = function() {    
  var l = arguments.length;    
  for (var i=0;i<l;i++){    
    this.length++;    
    this._array[this.end++] = arguments[i];    
  }    
}    
//pop method for user defined array type 'prototypeArray' prototypeArray.prototype.pop = function() {    
  var obj = null;    
  if (this.length>0){    
    this.length--;    
    obj = this._array[--this.end];    
    delete this._array[this.end];   
  }    
  return obj;    
}    
//creating an object of user defined array type 'prototypeArray' var myArray = new prototypeArray();    
//accessing push and pop methods of user defined array type 'prototypeArray'    
myArray.push("Test String")    
myArray.pop();  

一个用js代码自造的轮子,居然比c写的built-in函数跑的还要快,真是让人汗颜。

另外一个更简便的方式,就是记住这个简单的最佳实践:

少去改length!特别不要在循环中做pop()或length--之类的操作。如果要减,等到循环结束,一次性减到底就好了!

BTW,我们也要注意shift()、unshift()、splice()之类的操作,因为这些操作可能会改变大量数组元素的索引——按照稀疏数组的实现,显然会比单单改length更慢上许多!如果你真的需要shift()、unshift(),那还是自制一个类似上面的轮子吧(提示:上面代码的start属性就是为此准备的)。 

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com