JavaScript 引擎和 Just-in-Time 编译概念,Hot Function 的简单介绍

原文:JavaScript engines and Just-In-Time compilation: A beginner’s exploration, part 1

JavaScript 引擎本身也是一种软件,它将您华丽的 JavaScript 代码行转换为我们的机器可执行的二进制代码。

所有主要浏览器都开发了自己的 JavaScript 引擎。 Chrome 有 V8,Firefox 运行 SpiderMonkey(第一个 JavaScript 引擎的进化产品,由 Brendan Eich 在 90 年代为 Netscape Navigator 开发),Microsoft Edge 有 Chakra,Safari 有 Nitro。 Node.js 建立在 Chrome 的 V8 引擎之上。 物联网设备也可以有一个 JavaScript 引擎。

每个 JavaScript 引擎都负责使用 Ecma International 的 TC39 制定的 ECMAScript 规则和标准。

Why modern JavaScript engines do Just-In-Time compilation

JavaScript 是一门动态类型语言。

let x = 8let y = "Henlo fren"

这意味着无论何时你在 JavaScript 中声明一个变量,你都不必明确说明变量 x 存储的信息类型。 JavaScript 引擎在执行源代码时检查类型。

在静态类型语言(如 C++)中声明变量时,您必须显式指定变量值的类型。

int x = 8 string y = "Henlo fren"

有了如此严格的规则,静态类型语言可以具有更高的学习曲线。在尝试编写一个简单的程序之前,您必须更多地了解它的规则和类型。

然而,从编译器的角度来看,静态类型语言允许更快的性能。预先,当编译器开始将代码转换为可执行的机器代码二进制时,该语言为编译器提供了大量有关源代码的信息。

另一方面,像 JavaScript 这样的动态类型语言很少向编译器提供有关其类型的信息。这为编译器在生成机器代码之前创建了另一层工作,使其执行速度比静态编写语言的编译慢。

But fear not, this is where Just-In-Time compilation comes in!

最初开发 JavaScript 时,它旨在编写少量用于增强网页的脚本。随着开发人员开始构建和使用更多 JavaScript 框架和库,以及发出 AJAX 请求,对更好、更快性能的需求不断增长。

当 Chrome 于 2008 年推出时,谷歌还首次发布了其 V8 引擎,这是现代 JavaScript 引擎中的第一个。 V8 的主要特性之一是即时编译 - Just-In-Time compilation。

在 Ahead-of-Time 编译中,编译过程必须在系统运行可执行机器代码之前完成。有了 Just-In-Time compilation 这一新特性,V8引擎会根据需要编译源代码,在执行编译过程生成的机器码时收集类型信息,然后根据执行过程收集的信息重新编译源代码。两个进程之间的来回加快了执行过程的性能。

为了让 JavaScript 在动态类型的情况下仍能以最快的速度运行,JavaScript 引擎有一些巧妙的技巧。

像大多数现代 JavaScript 引擎一样,V8 有两个编译器:基线 (baseline)编译器和优化编译器。

当 V8 编译你的 JavaScript 代码时,它的解析器会生成一种叫做抽象语法树的东西。Ignition,V8 的基线编译器或解释器,从这个语法树生成字节码。 Ignition 忠实于它的即时编译特性,它编译 JavaScript 代码,运行它,编译它,运行它,来回,一遍又一遍。

在运行时,字节码被分析,引擎识别可以重新编译以获得最佳性能的部分(“热函数”),将该代码发送到 TurboFan,它是 V8 的优化编译器。正是因为即时编译,引擎才能够因为即时编译而识别这些所谓的“热功能”。

The + operator and V8 optimization

在她的精彩演讲 JavaScript 引擎中,V8 工程师 Franziska Hinkelmann 使用 + 运算符来解释 V8 的优化是如何工作的。

乍一看,加法运算符可能看起来很简单,任何编译器都可以编译和执行。 但是,如果您查看 Ecma 规范,在程序实际添加任何内容之前,引擎实际上需要执行很多步骤:

这些步骤中的每一步都在调用其他函数,而这些函数又可能调用其他函数,依此类推。所有引擎都必须遵循这些 Ecma 规范,因此 JavaScript 不仅仅是无法无天的。

因此,当您的程序有一个将两个整数相加的函数时,当您第一次调用该函数时,JavaScript 引擎会费力地完成这些步骤中的每一步,最终将您的两个整数相加。当它通过 JIT 过程(编译、运行、编译、运行、编译等)时,它意识到你的函数很热,很热,很热,因为你一直在调用它。从引擎在运行时收集的信息,它也意识到这个特定函数使用的数据类型只是整数。有了这些信息,V8 将您的代码发送到 TurboFan,它的优化器编译器,它为您的函数生成更好的机器代码。下次您再次调用该函数时,它会跳过冗长的 Ecma 步骤,您的函数将运行得更快。

但是当您决定在调用该函数时连接一些字符串而不是添加两个整数时会发生什么? V8 将该函数抛出到去优化器,将其发送回 Ignition,然后 Igntion 再次执行那些 Ecma 指定的步骤来运行该函数。

(0)

相关推荐

  • JavaScript内部原理:浏览器的内幕

    简介 Javascript 是一种奇怪语言,有些人喜欢它,有些人讨厌它.它有许多独特的机制,这些机制在其他流行语言中不存在,也没有对应的机制,还有突出明显的就是代码的执行顺序 了解浏览器环境,它的组成 ...

  • 什么是JavaScript的作用域

    作用域的概念 现代编程语言的最基本功能之一就是能够存储变量当中的值,以便于之后的使用于修改.也正是这个功能将状态带给了程序. 在JavaScript中,作用域就是一套设计良好的规则来存储变量. 简述编 ...

  • 深入解读ES6系列(一)

    前言: 哈喽小伙伴们,爱说'废'话的Z又回来了,欢迎来到Super IT曾的博客时间,我说啦这个月要带的福利,说了更的博客肯定不能水你们,要一起进步学习嘛,今天我就把我学习最经典的Blue的ES6掌握 ...

  • 「技术分享」WebAssembly能否重新定义前端开发模式?

    如果提及近年来让人最为兴奋的新技术,非WebAssembly 莫属.作为一种低级的类汇编语言,WebAssembly以紧凑二进制的格式存储,为C/C++, Rust等拥有低级内存的模型语言提供了新的编 ...

  • PS中图层蒙版的原理和用法 详解图层蒙版的概念 换天空再简单不过

    大家好,我是好色之图.疫情期间禁足在家,相信大家都闲的很无聊吧,写一节PS小教程,供小伙伴们闲暇之余学习使用,利用发呆的时间学习点新知识,也是不错的选择.本节内容是'图层蒙版的概念和使用方法'. 图层 ...

  • PS中图层蒙版的原理和用法详解图层蒙版的概念换天空再简单不过

    本节内容是'图层蒙版的概念和使用方法'. 图层蒙版是很多刚开始学习PS的伙伴头疼的工具之一,官方术语解释的太过专业和笼统,十分晦涩难懂,这也是PS工具书的特点之一了,在这一节里,我们尝试用老百姓的家常 ...

  • 飞碟的反重力引擎技术、飞船材料,以及外星人的身体结构介绍

    导读:本文是小编创作的关于''飞碟的反重力引擎技术.飞船材料,以及外星人的身体结构介绍''的资料,在这里与大家分享!这篇文章我主要从科学/物理学/工程学角度给大家详细阐述一下这些外星科技,包括飞碟的反 ...

  • 从零开始学乒乓球(3)击球点的基本概念和乒乓球技术的整体介绍

    上一章我讲了"横板乒乓球拍的握法及自我球感训练".这些内容光看是没有用的,需要你去练习,大概两三天就能掌握了.要想熟练掌握就需要长期的不断练习.这一章讲下击球点的基本概念和乒乓球技 ...

  • .net core 嵌入 js(javascript)脚本引擎

    dotNET跨平台 2021-07-07 以下文章来源于dotnet微服务 ,作者webmote dotnet微服务dotnet5是微软进阶跨平台后台服务开发的统一入口,随着微软在开源.开放的路上越走 ...

  • 编译 Unity 4.3.1 引擎源码

    引言 Unity 官方从 Unity 2017.1 版本开始,开源了引擎和编辑器的C#源码(源码地址:UnityCsReference),但核心的 C/C++ 部分源码并未开源. 编译环境 网上主要的 ...

  • 如何找到 SAP Spartacus 里某个 Component TypeScript 编译后生成的 JavaScript 位置

    需求 如何找到触发该网络请求的准确代码位置? 从 initiator 里查看调用栈上下文,一点头绪也没有. 找到触发该网络请求的控件的 selector:cx-register 在 Storefron ...

  • JavaScript字符串 - 概念

    字符串的概念 概念: 在JavaScript中将所有单引号或双引号括起来的都叫做字符串 字符串的创建: 1.通过new运算符创建 var str = new String ( "hello& ...

  • JavaScript数组 - 概念

    数组的概念及作用 我们来学习数组之前,先来复习一下数据类型 数据类型: 基本数据类型:数字.字符串.布尔值 特殊数据类型:null.undefined 符合数据类型:数组 为什么我们要来使用数组? 当 ...