开辟者大年夜赛路演 | 12月16日,技巧立异,北京不见不散
几个礼拜前,我们开端了一系列旨在深刻研究 JavaScript 及其实际工作方法的系列文┞仿:我们认为经由过程懂得 JavaScript 的构建块以及它们若何一路协作的,你将可以或许编写更好的代码和应用法度榜样。
本系列的第一篇文┞仿重点介绍了引擎,运行时和调用客栈的概述。第二篇文┞仿精深刻到 Google V8 JavaScript 引擎的内部。我们还将供给一些关于若何编写更好的 JavaScript 代码的快速技能 - 我们的 SessionStack 开辟团队在构建产品时所遵守的最佳实践。
概览
接下来将评论辩论内联缓存的一般概念(如不雅您没有时光经由过程膳绫擎的深刻懂得)。
JavaScript 引擎是履行 JavaScript 代码的法度榜样或说冥器。 JavaScript 引擎可以作为标准说冥器或即时编译器,它以某种情势将 JavaScript 编译为字节码。
垃收受接收集
下面是一个实现了 JavaScript 引擎的风行项目列表:
- V8 — 开源,由 Google 开辟,用 C ++ 编写
- Rhino — 由 Mozilla 基金会治理,开源,完全用 Java 开辟
- SpiderMonkey — 是第一个支撑 Netscape Navigator 的 JavaScript 引擎,今朝正供 Firefox 应用
- JavaScriptCore — 开源,由苹不雅公司为 Safari 开辟
- KJS — KDE 的引擎,最初由 Harri Porten 为 KDE 项目中的 Konqueror 网页浏览器开辟
- Chakra (JScript9) — Internet Explorer
- Chakra (JavaScript) — Microsoft Edge
- Nashorn, 作为 OpenJDK 的一部分,由 Oracle Java 说话和对象组编写
- JerryScript — 物联网的轻量级引擎
由 Google 构建的 V8 引擎是开源的,用 C ++ 编写。 此引擎被用在 Google Chrome 中。 与其他引擎不合的是,V8 也被用于风行的 Node.js 中。

V8 最初是被设计用来进步网页浏览器内部 JavaScript 履行的机能。为了获得更快的速度,V8 将 JavaScript 代码翻译成更高效的机械代码,而不是应用说冥器来翻译代码。它经由过程应用 JIT(Just-In-Time)编译器(如 SpiderMonkey 或 Rhino(Mozilla)等很多现代 JavaScript 引擎)来将 JavaScript 代码编译为机械代码。 这里的重要差别在于 V8 不生成字节码或任何中心代码。
V8 曾有两个编译器
在 V8 的 5.9 版本出来之前(本年早些时刻宣布),引擎应用了两个编译器:
- full-codegen - 一个简单并且速度异常快的编译器,可以生成简单且相对较慢的机械代码。
- Crankshaft - 一种更复杂(Just-In-Time)的优化编译器,生成高度优化的代码。
一个名为“C2”的新隐蔽类会被创建,如不雅将一个属性 “y” 添加到一个 Point 对象(已经包含属性“x”),一个类转换会添加到“C1”,则隐蔽类应当更改为“C2”,点对象的隐蔽类更新为“C2”。
V8 引擎也在内部应用多个线程:
- 主线程完成您期望的义务:获代替码,编译并履行它
- 还有一个零丁的线程用于编译,以便主线程可以持续履行,而前者正在优化代码
- 一个 Profiler 线程,它会告诉运行时我们花了很多时光,让 Crankshaft 可以优化它们
- 一些线程处理垃收受接收集器
当第一次履行 JavaScript 代码时,V8 应用 full-codegen 编译器,直接将解析的 JavaScript 翻译成机械代码而一向行任何转换。这使得它可以异常快速地开端履行机械代码。请留意,V8 不应用中心字节码,大年夜而不须要说冥器。
V8 应用另一种被称为内联缓存的技巧来竽暌古化动态类型说话。内联缓存依附于产生在雷同类型的对象上的雷同办法的反复调用的不雅察上。内嵌缓存的更多解释可以在这里找到。
当你的代码运行了一段时光,分析器线程已经收集了足够的数据来断定哪个办法应当被优化。
接下来,Crankshaft 大年夜另一个线程开端优化。它将 JavaScript 抽象语法树转换为被称为 Hydrogen 的高等静态单分派(SSA)表示,尝尝试优化 Hydrogen 图。大年夜多半优化都是在这个级别完成的。
内联代码
第一个优化是提前尽可能多地内联代码。内联是将被调用函数的主体调换为调用站点(调用函数的代码行)的过程。这个简单的步调使得下面的优化更有意义。

隐蔽类
JavaScript 是一种基于原型的说话:没有类和对象而是应用克隆创建的。 JavaScript 也是一种动态编程说话,这意味着属性可以在实例化后便利地添加或大年夜对象中移除。
大年夜多半 JavaScript 说冥器应用类似字典的构造(基于散列函数)来存储对象属性值袈溱内存中的地位。这种构造使得在 JavaScript 中检索一个属性的值比在 Java 或 C# 如许的非动态编程说话中的计算量要大年夜得多。在 Java 中,所有的对象属性都是在编译之前由一个固定的对象决定的,并且不克不及在运行时动态添加或删除(当然,C#的动态类型是另一个主题)。是以,属性的值(或指向这些属性的指针)可以作为持续的缓冲区存储在内存中,每个值之间有一个固定的偏移量。偏移量的长度可以很轻易地根据属性类型来肯定,而在运行时属性类许可以改变的 JavaScript 中这是弗成能的。
推荐阅读
开辟者大年夜赛路演 | 12月16日,技巧立异,北京不见不散 为什么今天要写出来?为什么是今天要写如许一篇文┞仿?这篇文┞仿是我混迹linux世界这么久一向想说的很多话的集合,大年夜岁首?年>>>详细阅读
本文标题:解读JavaScript之V8引擎及优化代码的5个技巧
地址:http://www.17bianji.com/lsqh/39844.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示