转载请注明出处:
Google研发的V8 JavaScript引擎性能优异。我们请熟悉内部程序实现的作者依源代码来看看V8是如何加速的。
作者:Community Engine公司研发部研发工程师Hajime Morita
Google的Chrome中的V8 JavaScript引擎,由于性能良好吸引了相当的注目。它是Google特别为了Chrome可以高速运行网页应用(WebApp)而开发的。Chrome利用Apple领导的WebKit研发计划作为渲染引擎(Rendering engine)。 WebKit也被用在Safari浏览器中。WebKit的标准配备有称为JavaScriptCore的JavaScript引擎,但Chrome则以V8取代之(图1)。
V8开发小组是一群程序语言专家。核心工程师Lars Bak之前研发了HotSpot,这是用在Sun Microsystems公司开发的Java虚拟机器(VM)之加速技术。他也在美国的Animorphic Systems公司(于1997年被Sun Microsystems所并购)研发了称为Strongtalk的实验Smalltalk系统。V8充分发挥了研发HotSpot和Strongtalk时所获得的知识。
图1 开发自己的JavaScript引擎 Apple的Safari和Google的Chrome使用相同的渲染引擎。配有JavaScriptCore的WebKit渲染引擎在JavaScript引擎中是标准配备,但在Chrome却被V8取代了.
高速引擎的需求
Google研发小组在2006年开始研发V8,部分的原因是Google对既有JavaScript引擎的执行速度不满意。我认为当时JavaScript引擎很慢是有两个原因的:开发的历史背景,以及JavaScript语言的复杂性。
JavaScript存在至少10年了。在1995年,它出现在网景(Netscape Communications)公司所研发的网页浏览器Netscape Navigator 2.0中。然而有段时间人们对于性能的要求不高,因为它只用在网页上少数的动画、交互操作或其它类似的动作上。(最明确的是为了减少网络传输,以提高效率和改善交互性!)浏览器的显示速度视网络传输速度以及渲染引擎(rendering engine)解析HTML、CSS(cascading style sheets, CSS)及其他代码的速度而定。浏览器的开发工作优先提升渲染引擎的速度,而JavaScript的处理速度不是太重要。同时出现的Java有相当大的进步,它被做得愈来愈快,以便和C++竞争。
然而,在过去几年,JavaScript突然受到广泛使用。原因是之前被当成桌面应用的软件(其中包括Office套件等),现已成为可以在浏览器中执行的软件。
Google本身就推出了好几款JavaScript网络应用,其中包括它的Gmail电子邮件服务、Google Maps地图数据服务、以及Google Docs office套件。
这些应用表现出的速度不仅受到服务器、网络、渲染引擎以及其他诸多因素的影响,同时也受到JavaScript本身执行速度的影响。然而既有的JavaScript引擎无法满足新的需求,而性能不佳一直是网络应用开发者最关心的。
语言本身的问题
JavaScript语言的规范现在性能压力巨大。例如,这在当它判定变量类型时就相当显而易见。如C++和Java等主流语言采用静态类型(static typing)。当代码编译时,就可宣告变量类型。由于不需要在执行期间检查数据类型,因此静态类型占有性能上的优势。
在例如C++和Java等一般处理系统中,fields*和methods*等的内容是以数组储存,以1:1位移(offset)对应fields和methods等的名称(图2)。个别变量和methods等储存的位置,是针对各个类定义的。在C++和Java等语言中,已事先知道所存取的变量(类)类型,所以语言解释系统(Interpreting system)只要利用数组和位移来存取field和method等。位移使它只要几个机器语言指令,就可以存取field、找出field或执行其他任务。
图2 JavaScript和C++、Java的不同 C++、Java及其他处理系统将fields和methods等,以它们的名称以1:1对应数组内的位移值储存在数组中。会事先知道要存取的变量类型(类),因此可以只用数组和位移就可以存取fields和methods等。然而在JavaScript,个别的对象都有自己属性和方法等的表格。每一次程序存取属性或是呼叫方法时,都必须检查对象的类型并执行适当的处理。
* Field:属对象的变量。C++中称为成员变量。
* Method:属对象的处理类型。C++中称为成员函式。
* Property属性:JavaScript属性是对象自己拥有的变量。在JavaScript中,属性中不只可以是标准的值,也可以是methods。