日期:2014-05-16  浏览次数:20314 次

关于JScript 5.6及其之前(IE6)引擎的创建对象的性能问题

http://hax.iteye.com/blog/104393【2007-07-23 11:47

这个问题很早就知道,即在对象数量达到一定程度的时候(例如50000),创建新对象的速度明显下降。过去在和aimingoo共事的时候(2006年的某个时候),我花时间研究了一下。?

当时我首先猜测是否是在一个closure里,因为当前[[scope]]下可访问的变量太多造成的,即我怀疑是jscript的name resolve的问题,但实际写了一些测试用例证明这个猜测是错误的。任何时候,只要存在大量对象,不管在当前创建新对象的function里是否能访问到已经存在对象,性能都十分低下。?

不知怎的,我开始怀疑是否是垃圾回收的问题。于是我尝试在创建对象的循环里插入了CollectGarbage的强制调用。按说GC调用会明显的降低性能(不涉及创建对象的代码中也确实如此),但是我测试的结果是,降低的并不多!而且随着我调节参数来确定每创建多少个对象调用一次GC,发现统计性能结果呈一种波浪形(按说应该是呈线性),在256及其倍数的对象个数左右,是性能损失最少的地方。由此,我断定,JScript在256次创建对象后会调用一次GC(我的假设是:GC很可能是另一个线程在运行,因此两次非常靠近的GC调用有一定概率会变为一次),而JScript那原始的计数GC的性能很低。反复的调用GC,这就是JScript性能下降的罪魁祸首。?

最近两天看到ajaxan上的综述文章,证明了我的推理:http://ajaxian.com/archives/garbage-collection-in-ie6?

实际上该文指出,2003年的时候,IE团队的自己人就说明过这个问题:http://blogs.msdn.com/ericlippert/archive/2003/09/17/53038.aspx?

特别是在comments中,作者Eric说:?
The heuristics are we do a GC on the next statement after any one of the following limits are passed since the previous GC:?
0x100 variables/temps/etc allocated?
0x1000 array slots allocated?
0x10000 bytes of strings allocated?
...As you can see it's a pretty naive heuristic.?

对此,Brendan Eich回应道:?
Sorry, that heuristic is not naive, it's just plain wrong.? Allocation of particular types or slots does not predict garbage, and the magnitudes are wrong compared to the cost of GC'ing a large live object graph.?


我非常同意BE同志的看法,这不是幼稚,而是错误。尽管IE7已经修复了这个bug,但是在很长的时间里,我们仍然要考虑IE6,不得不仔细平衡对象数量的开销,为此付出许多额外代价。?

MS最后给了一个hotfix:http://support.microsoft.com/kb/919237,然而所谓hotfix,就是仍然不是强制安装的。sigh!