通过Tracemonkey,Squirrelfish和V8项目,有很多大写的C,大写的S计算机科学进入Javascript。这些项目(或其他项目)中有没有解决DOM操作的性能问题,或者它们纯粹是与Javascript计算相关的?
发布于 2009-01-02 08:42:35
纯DOM操作(getElementById/标记名/选择器、nextChild等)的性能不受影响,因为它们已经在纯C++中。
JS引擎的改进将如何影响性能在一定程度上取决于用于性能改进的特定技术,以及DOM->JS桥的性能。
前者的一个例子是TraceMonkey依赖于对JS函数的所有调用。因为跟踪有效地内联了JS命中不能被内联的代码(本机代码、真正的多态递归、异常处理程序)的任何点的执行路径,所以跟踪被中止,并且执行返回到解释器。TM开发人员正在做相当多的工作来改进可跟踪的代码量(包括处理多态递归),然而实际地跟踪对任意本机函数的调用(例如。DOM)是不可行的。出于这个原因,我相信他们正在考虑用JS实现更多的DOM (或者至少以一种JS友好的方式)。也就是说,当代码是可跟踪的时,TM可以做一件特别好的工作,因为它可以将大多数“对象”降低到更有效和/或本地等价(例如。使用机器int而不是JS Number实现)。
JavaScriptCore ( SquirrelFish Extreme所在的地方)和V8有一种更相似的方法,它们都立即对所有JS代码进行即时处理,并生成更具投机性的代码(例如.如果你在做a*b
,他们会生成假设a
和b
是数字的代码,如果不是,就会退回到异常缓慢的代码中)。与跟踪相比,这有许多好处,即您可以jit所有代码,而不管它是否调用本机代码/抛出异常等,这意味着单个DOM调用不会破坏性能。缺点是所有的代码都是投机性的-- TM将内联调用Math.floor,等等,但是JSC/V8能做的最好的事情是等同于a=Math.floor(0.5)
-> a=(Math.floor == realFloor) ? inline : Math.floor(0.5)
,这在性能和内存使用上都有代价,它也不是特别可行。这样做的原因是前期编译,而TM只有运行后的JIT代码(因此确切地知道调用了什么函数) JSC和V8没有真正的基础来做出这样的假设,基本上必须猜测(目前都没有尝试这样做)。为了弥补这个问题,V8和JSC做了一件事,那就是跟踪它们过去看到的东西,并将其合并到执行路径中,两者都使用组合技术来执行缓存,在特别热门的情况下,它们会重写一小部分指令流,而在其他情况下,它们会保留带外缓存。一般说来,如果你有这样的代码
a.x * a.y
V8和JSC将检查两次“隐式类型”/“结构”--每次访问一次,然后检查a.x
和a.y
是否都是数字,而TM将生成只检查一次a
类型的代码,并且可以(在所有条件相同的情况下)将a.x
和a.y
相乘,而不检查它们是否为数字。
如果你目前看的是纯执行速度,就会有一些复杂的东西,因为每个引擎在某些任务上确实比其他引擎做得更好-- TraceMonkey在许多纯数学测试中获胜,V8在高度动态的情况下获胜,如果存在混合情况,则JSC获胜。当然,虽然今天是正确的,但明天可能不会,因为我们都在努力提高性能。
我提到的另一个问题是DOM<->JS绑定成本--这实际上对web性能起着非常重要的作用,在Dromaeo基准测试中,最好的例子是Safari3.1/2 vs Chrome。Chrome基于WebKit的Safari3.1/2分支,因此假定DOM性能相似是合理的(编译器的差异可能会导致一定程度的差异)。在这个基准测试中,Safari3.1/2实际上击败了Chrome,尽管它有一个明显慢得多的JS引擎,这基本上是由于JSC/WebCore (WebKit的dom/rendering/等)和V8/WebCore之间更有效的绑定
目前来看TM的DOM绑定似乎不公平,因为他们还没有完成他们想要做的所有工作(唉),所以他们只是求助于解释器:-(
。。
嗯,这比预期的时间要长一些,所以对原始问题的简短回答是“这取决于”:D
https://stackoverflow.com/questions/406097
复制相似问题