inside the V8 engine + 5 tips on how to write optimized code
两周前咱们开始了js深刻了解以及它如何的工做原理的研究:咱们认为经过了解js的代码构建和他们的运行机制能够写出更好的代码和app。
前面的博文主要是js引擎概述,运行和堆栈。第二篇会深刻谷歌V8的js引擎部分,咱们也会提供一点点关于如何编写更好的js代码的建议-最好java
js引擎是一个程序或者执行js代码解析器。js引擎能够实现为一个标准的翻译,或者以某种形式将js代码即时编译成字节码。 下面是流行的js执行引擎清单列表:node
由google开发V8引擎是开源的,用c++编写。这个引擎用于Google Chrome。不像其余的引擎,当前流行的node.js也是基于V8运行。 c++
当开始执行js代码,v8使用full-codegen直接解析js翻译成机器码,没有任何转换。这容许它开始执行机器代码很是快。注意v8不使用中间字节码表示这种方式不须要翻译。web
当你的代码运行一段时间后,解析器线程会汇集足够的数据告诉咱们哪些方法必须优化。 接下来,Crankshaft开始在另外一条线程上优化。它将js抽象语法树(syntax tree )转换成一个叫Hydrogen 的高级静态单元分配表示 (SSA) ,并且尝试去优化 Hydrogen这个图。大多数的优化是在这级完成的。编程
首次优化尽量多的提早嵌入代码。代码嵌入是将使用函数的地方(调用函数的那一行)替换成被调用函数的本体。这个简单的步骤可使接下来的优化更有意义。 浏览器
js是一个基于原型链的语言:它没有类和对象是经过克隆产生的。js也是一个动态编程语言,这意味着在对象实力化之后能够很简单增长或者移除属性。 大多数js解析器使用相似字典同样的结构(基于散列函数) 去储存对象属性值在内存中的地址。这种构造使js在检索对象属性值上比其余相似java,c++等动态语言,花费更大的计算量。在java中,全部的对象属性在编译以前都已经被固定的对象容器决定。并且在运行时不能够动态的添加或者删除属性。(c++的动态类型是另外一个话题)。结果,每个属性的值可以以连续的buffer储存在内存中,在每一个属性值之间有一个偏移量。这个偏移量的长度很容易根据属性类型决定。然而在js中这是不可能的,由于js的属性值能够在运行时改变。 由于使用字典去查找对象属性在内存中的地址的效率很低,V8使用了一个不一样的方法代替:隐藏类。隐藏类与在java等语言中使用的固定对象布局的工做方式相似,除了他在运行时被建立。来让咱们看一下真实的代码:缓存
function Point(x,y){
this.x = x;
this.y = y;
}
var p1 = new Point(1,2);
复制代码
一旦 new Point(1,2) 被调用,V8会建立一个名为 C0 的隐藏类。 session