V8引擎是如何工作?

更新日期: 2018-11-12阅读: 2.7k标签: 引擎

V8是google开发的JavaScriptV8是google开发的JavaScript引擎, 它是 开源的 ,而且是用C++编写的。它用于客户端(Google Chrome)和服务器端(node.js)JavaScript应用程序

V8最初旨在提高Web浏览器中JavaScript执行的性能。为了提升速度,V8将JavaScript代码转换为更高效的机器代码,而不是使用解释器。它通过实现 JIT(即时)编译器将JavaScript代码编译成机器代码,就像许多现代JavaScript引擎(如SpiderMonkey或Rhino(Mozilla))所做的那样。与V8的主要区别在于它不会产生字节码或任何中间代码

本文的目的是展示和理解 V8如何工作,以便为客户端或服务器端应用程序生成优化的代码。如果您已经在问自己“我应该关心JavaScript性能吗?”那么我将回答Daniel Clifford(技术主管和V8团队经理)的一句话:“这不仅仅是让您当前的应用程序运行得更快,而是关于实现你过去从未做过的事情“。


隐藏的class

JavaScript是一种基于原型的语言:no classes,并且使用克隆过程创建对象(原型链)。JavaScript也是动态类型的:类型和类型信息不是显式的,属性可以动态添加到对象中或从中删除。有效访问类型和属性是V8的首要挑战。而不是使用类似字典的数据结构来存储对象属性和进行动态查找来解析属性位置(就像大多数JavaScript引擎一样),V8在运行时创建隐藏类,以便具有内部表示类型系统和改善属性访问时间。

让我们有一个Point函数和两个Point对象的创建:


如果布局相同(这里是这种情况),则p和q属于由V8创建的相同隐藏类。这突出了使用隐藏类的另一个优点:它允许V8对属性相同的对象进行分组。这里p和q有一定的代码优化

现在,让我们假设我们想在我们的q对象之后添加一个z属性,就在它声明之后(对于动态类型语言来说这是完全没问题的)。

V8将如何处理这种情况?事实上,每当构造函数声明一个属性并跟踪隐藏类的变化时,V8 就会创建一个新的隐藏类。为什么?因为如果创建了两个对象(p和q)并且在创建后将成员添加到第二个对象(q),则V8需要保留最后创建的隐藏类(对于第一个对象p)并创建一个新对象(对于第二个对象q)与新成员。


每次创建一个新的隐藏类时,前一个隐藏类都会更新一个类转换,指示必须使用哪个隐藏类。

代码优化

因为V8为每个属性创建一个新的隐藏类,所以应该将隐藏的类创建保持在最低限度。为此,请尽量避免在创建对象后添加属性,并始终以相同的顺序初始化对象成员(以避免创建不同的隐藏类树)。

\ [Update ]另一个技巧:单态操作是仅对具有相同隐藏类的对象起作用的操作。当我们调用一个函数时,V8会创建一个隐藏类。如果我们用不同的参数类型再次调用它,V8需要创建另一个隐藏类:首选单态代码到多态代码


有关V8如何优化JavaScript代码的更多示例

标记值

为了有效地表示数字和JavaScript对象,V8表示具有 32位值。它使用一个位来知道它是一个对象(flag = 1)还是一个整数(flag = 0),这里称为SMall Integer或 SMI ,因为它的31位。然后,如果数值大于31位,则V8将对该数字进行选择,将其变为双精度并创建一个新对象以将数字放入其中。

代码优化:尽可能使用31位带符号数字,以避免对JavaScript对象进行消耗性能的封装操作。

数组

V8使用两种不同的方法来处理数组:

  • 快速元素:专为那些键组非常紧凑的阵列而设计。它们具有线性存储缓冲区,可以非常有效地访问它。

  • 字典元素:专为稀疏数组而设计,它们内部没有所有元素。它实际上是一个哈希表,它的性能消耗比“快速元素”更昂贵。

代码优化:确保V8使用“快速元素”来处理数组,换句话说,避免使用稀疏数组。另外,尽量避免预先分配大型数组。最后,不要删除数组中的元素:它使键集稀疏。


V8如何编译JavaScript代码?

V8有两个编译器!

  • 一个“完整”编译器,可以为任何JavaScript生成良好的代码:良好但不是很好的JIT(即时编译器)代码。此编译器的目标是快速生成代码。为了实现其目标,它不进行任何类型分析,也不了解类型。相反,它使用内联缓存或“IC”策略来在程序运行时优化有关类型的知识。IC效率非常高,速度可提高20倍。

  • 优化编译器,可为大多数JavaScript语言生成出色的代码。它稍后会重新编译热门功能。优化编译器从内联缓存中获取类型,并决定如何更好地优化代码。但是,某些语言功能尚不支持,例如try / catch块。(try / catch块的解决方法是在函数中编写“非稳定”代码并在try块中调用函数)

代码优化:V8还支持去优化:优化编译器从内联缓存中对不同类型做出假设,如果这些假设无效则会进行去优化。例如,如果生成的隐藏类不是预期的类,则V8会抛弃优化的代码并返回到完整编译器以从内联缓存中再次获取类型。此过程很慢,应该通过在优化后尝试不更改功能来避免。


资源


原文链接: thibaultlaurens.github.io  
翻译来源:https://www.zcfy.cc/article/how-the-v8-engine-works


链接: https://www.fly63.com/article/detial/1325

Javascript模版引擎mustache.js简介

最近使用ELK的sentinl进行告警配置,sentinl的邮件通知支持mustache。mustache的核心是标签和logic-less.标签: 定义模板的时候,使用了{{name}}、{{#systems}}{{/systems}}标记. 这就是mustache的标签,只不过用{{}}替代了<>

JavaScript 引擎

编写Web代码有时会让开发人员编写一系列字符并像魔术那样神奇,这些字符会在浏览器中变成具体的图像,文字和动作。了解该技术可以帮助开发人员更好地调整他们作为程序员的技能

JavaScript物理引擎之Matter.js与Box2d性能对比

在挑选JavaScript 2D物理引擎的时候,不外乎两种主流的选择:第一种是老牌的Box2D,最开始的版本是C++实现的,后来有了很多种实现,比如flash版本和js版本,第二种是新潮的matter-js,matter-js比较轻量,API和文档都比较有友好。

JS 引擎 V8 发布 v7.4,性能又大幅提高了

JavaScript 引擎 V8 发布了 7.4 版本,目前处于 beta 阶段,正式版将于几个星期后与 Chrome 74 Stable 一起发布。此版本带来了一些新特性,并极大提升了性能。

精读《V8 引擎 Lazy Parsing》

本周精读的文章是 V8 引擎 Lazy Parsing,看看 V8 引擎为了优化性能,做了怎样的尝试吧!这篇文章介绍的优化技术叫 preparser,是通过跳过不必要函数编译的方式优化性能。

JavaScript引擎是如何工作的?从调用栈到Promise你需要知道的一切

你有没有想过浏览器是如何读取和运行 JavaScript 代码的吗?这看起来很神奇,但你可以学到一些发生在幕后的事情。让我们通过介绍 JavaScript 引擎的精彩世界在这种语言中尽情畅游。

从Google V8引擎剖析Promise实现

本文阅读的源码为Google V8 Engine v3.29.45,此版本的promise实现为js版本,在后续版本Google继续对其实现进行了处理。引入了es6语法等,在7.X版本迭代后,逐渐迭代成了C版本实现。

V8引擎-枚举+位运算实现参数配置

基本上从初始化引擎,到Isolate、handleScope、Context一直到编译其实都有记录,但是实在是无从下手。虽说我的博客也没有什么教学意义,但是至少也需要有一个中心和结论。

Node js 视图引擎

Node js 视图引擎就像 Laravel 中的 Blade。其最基本的定义是,视图引擎是帮助我们用比通常更短、更简单的方式编写 HTML 代码并重用的工具。此外,它还可以从服务器端导入数据并渲染最终的 HTML

规则引擎解决方案浅析

用于页面,流程,扩展点实现的选择;输出结果:实现的位置;编排无数的条件积木和行为积木,达到业务逻辑计算,券库存消减的目的;输出结果:商品重计算后的价格;通过订单,售后单,会员等信息编排和判断

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!