编译器和解释器:V8是如何执行一段JS代码的

编译器和解释器:V8是如何执行一段JS代码的

  • 背景
    • 编译器和解释器
    • V8 执行 JavaScript 代码
      • 1. 生成抽象语法树(AST)和执行上下文
      • 2. 生成字节码
      • 3. 执行代码
    • JavaScript 的性能优化

背景

前端工具和框架迭出不穷,而且还不断有新的出现,要想追赶上这些工具和框架的更新速度,你就需要抓住那些本质的知识,然后才能更加轻松地理解这些上层应用。比如了解 V8 执行机制,能帮助你从底层了解 JavaScript,也能帮助你深入理解语言转换器 Babel、语法检查工具 ESLint、前端框架 Vue 和 React 的一些底层实现机制。

要深入理解 V8 的工作原理,首先关注以下几个概念:编译器(Compiler)、解释器(Interpreter)、抽象语法树(AST)、字节码(Bytecode)、即时编译器(JIT)。

编译器和解释器

之所以存在编译器和解释器,是因为机器不能直接理解我们写的代码,所以在执行程序之前,需要将我们所写的代码“翻译”成机器能读懂的机器语言。按语言的执行流程,可以将语言分为编译型语言和解释型语言。

编译型语言在程序执行之前,需要经过编译器的编译过程,编译后直接保留机器能读懂的二进制文件,运行程序时直接运行该二进制文件即可。比如 C/C++、GO语言等。

而由解释型语言编写的程序,在每次运行时都需要通过解释器对程序进行动态解释和执行。比如 Python、JavaScript语言等。

具体流程可以参考下图

编译器和解释器“翻译”代码

V8 执行 JavaScript 代码

1. 生成抽象语法树(AST)和执行上下文

高级语言是开发者可以理解的语言,但是让编译器或者解释器来理解就非常困难了。对于编译器和解释器来说,它们能理解的就是 AST。所以无论是编译型还是解释型语言,编译过程中都会生成一个 AST。这和渲染引擎将 HTML 格式文件转换为计算机可以理解的 DOM 树的情况类似。结合下面这段示例代码来直观地感受下什么是 AST:

var myname = 'yy'
function foo() {
  return 23
}
myname = 'qq'
foo()

这段代码经过 javascript-ast 站点处理后,生成的 AST 结构如下:

在这里插入图片描述

图中可以看出,AST 的结构和代码的结构非常相似,可以将其看成是代码结构化的表示,编译器或解释器后续的工作都需要依赖于 AST 而不是源代码。

AST 是一种非常重要的数据结构,在很多项目中都有着广泛的使用。例如 Babel、ESLint等。
Babel 是一个被广泛使用的代码转码器,可以将 ES6 代码转为 ES5 代码,Babel 的工作原理就是先将 ES6 源码转换为 AST,然后再将 ES6 语法的 AST 转换为 ES5 语法的 AST,最后利用 ES5 的 AST 生成 JavaScript 源代码。
ESLint 是一个用来检查 JavaScript 编写规范的插件,它的检测流程也是将源码转换为 AST,然后再利用 AST 来检查代码规范化的问题

那么,AST 是如何生成的呢?

第一阶段是分词(tokenize),又称为词法分析,其作用是将一行行源代码拆解成一个个 token(所谓 token,指的是语法上不可能再分的、最小的单个字符或字符串)

在这里插入图片描述

图中简单定义了一个 myname 的变量,生成了 4token,而且它们代表的属性还不一样。

第二阶段是解析(parse),又称为语法分析,其作用是将上一步生成的 token 数据,根据语法规则转为 AST。当然,如果源码存在语法错误,这一步就会终止,并抛出一个“语法错误”。

这就是 AST 的生成过程,先分词,再解析。有了 AST 后,接下来 V8 就会生成该段代码的执行上下文。至于执行上下文的具体内容,可以参考 JS变量和函数提升 以及 作用域链和闭包 这两篇文章。

2. 生成字节码

有了AST和执行上下文后,那接下来的第二步,解释器 Ignition 就登场了,它会根据 AST 生成字节码,并解释执行字节码。

其实一开始 V8 并没有字节码,而是直接将 AST 转换为机器码,由于执行机器码的效率是非常高效的,所以这种方式在发布后的一段时间内运行效果是非常好的。但是随着 Chrome 在手机上的广泛普及,特别是运行在 512M 内存的手机上,内存占用问题也暴露出来了,因为 V8 需要消耗大量的内存来存放转换后的机器码。为了解决内存占用问题,V8 团队大幅重构了引擎架构,引入字节码,并且抛弃了之前的编译器,最终花了将进四年的时间,实现了现在的这套架构。

那什么是字节码呢?为什么引入字节码就能解决内存占用问题呢?

字节码就是介于 AST 和机器码之间的一种代码。但是与特定类型的机器码无关,字节码需要通过解释器 Ignition 将其转换为机器码后才能执行。

下图是对比高级代码、字节码和机器码的示意图

在这里插入图片描述

从图中可以看出,机器码所占用的空间远远超过了字节码,所以使用字节码可以减少系统的内存使用。

3. 执行代码

通常,一段第一次执行的字节码,解释器 Ignition 会逐条解释执行(相信你已经发现,解释器 Ignition 除了负责生成字节码之外,它还要解释执行字节码),在执行过程中,如果发现有热点代码(HotSpot)(一段会被重复执行多次的代码),后台编译器 TurboFan 会将该段热点的字节码编译为高效的机器码,然后当再次执行这段被优化的代码时,只需要执行编译后的机器码就可以了,大大提升了代码的执行效率。

V8 的解释器和编译器的取名也很有意思。解释器 Ignition 时点火器的意思,编译器 TurboFan 时涡轮增压的意思,寓意着代码启动时通过点火器慢慢发动,一旦启动,涡轮增压介入,其执行效率随着执行时间越来越高效率,因为热点代码都被 TurboFan 转换了机器码,直接执行机器码就省去了字节码“翻译”为机器码的过程。

其实字节码配合解释器和编译器是最近很火的一项技术,比如 Java 和 Python 的虚拟机都是基于这种技术实现的,我们把这种技术称为即时编译(JIT),可以结合下图看 JIT 的工作过程:

在这里插入图片描述

JavaScript 的性能优化

虽然在 V8 诞生之初,也出现过一系列针对 V8 专门优化 JavaScript 性能的方案,例如隐藏类、内联缓存等,不过随着 V8 的架构调整,你越来越不需要这些微优化策略了,相反,对于优化 JavaScript 执行效率,你应该将优化的中心聚焦到单次脚本的执行时间和脚本的网络下载上:

  • 提升单次脚本的执行效率,避免 JavaScript 的长任务霸占主线程,使得页面快速响应交互
  • 避免大的内联脚本,因为在解析 HTML 的过程中,解析和编译也会占用线程
  • 减少 JavaScript 文件的容量,因为更小的文件会提升下载速度,并且占用更低的内存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/313020.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ChatGLM基于LangChain应用开发实践(二)

一、使用notion样例数据构建知识库 这里使用LangChain开发框架支持的Faiss构建知识向量库,通过以下命令来安装Faiss的GPU版本: pip install faiss-gpu 简单起见,向量库会以文件的形式存储到磁盘,具体步骤如下: 引入…

项目经理周报,月报编写模板

一、项目基本情况 二、本周工作总结 三、下周工作计划 软件开发管理全文档获取:软件开发全套资料-CSDN博客

linux高级篇基础理论十一(GlusterFS)

♥️作者:小刘在C站 ♥️个人主页: 小刘主页 ♥️不能因为人生的道路坎坷,就使自己的身躯变得弯曲;不能因为生活的历程漫长,就使求索的 脚步迟缓。 ♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏:云计算技…

格密码:如何找最近的格点(CVP问题)

目录 一. 摘要 二. 介绍 2.1 简单的CVP问题 2.2 Gram-Schmidt向量 2.3 KZ基 三. 格密码的基本符号 四. CVP问题的发展 五. 如何解决CVP问题 5.1 随机取整算法 5.2 Babai算法随机取整 5.3 小结 六. 推荐论文 一. 摘要 本文章将解释如何利用随机取整算法&#xff08…

【微信小程序开发】深入学习小程序开发之功能扩展和优化

前言 随着移动互联网的快速发展,微信小程序作为一种轻量级应用,已经逐渐成为许多企业和个人进行业务推广和服务提供的重要平台本文将详细介绍 微信小程序开发的功能扩展和优化,帮助开发者更好地提升小程序的用户体验和性能。 一、功能扩展 …

【qt】opencv导入pro

我的sdk0文件夹在opencv003项目下,使用opencv451 INCLUDEPATH $$PWD/sdk0/opencv/includeCONFIG(release, debug|release) {LIBS -L$$PWD/sdk0/opencv/lib/ -lopencv_world451opencv.files $$PWD/sdk0/opencv/bin/opencv_world451.dllopencv.path $$OUT_PWD/Re…

Shopify绑定Facebook收费吗?付款方式是什么?-站斧浏览器

Shopify绑定Facebook收费吗? 答案是:Shopify绑定Facebook并不收取额外费用。Shopify和Facebook之间的绑定是免费的,卖家可以充分利用这一功能来扩展他们的在线业务。通过将商店与Facebook Page相连接,卖家可以将产品目录同步到Fa…

【EI会议征稿通知】2024年机器学习与智能计算国际学术会议(MLIC 2024)

2024年机器学习与智能计算国际学术会议(MLIC 2024) 2024 International Conference on Machine learning and intelligent computing 智能计算与机器学习被广泛应用于大数据分析、人工智能、智能制造、智能交通、智能电网、智慧城市、智慧医疗、金融科…

imx6ull基于Linux 5.10.19移植OV2640驱动过程记录及问题解决

硬件使用正点原子的阿尔法开发板&#xff0c;摄像头原理图如下&#xff1a; OV2640是淘宝上买的0v2640模组&#xff0c;如下&#xff1a; 添加设备树节点如下&#xff1a; &i2c2 {clock-frequency <100000>;pinctrl-names "default";pinctrl-0 <&am…

gazebo怎样快速导入其他机器人及其配置

只要拿过来100块钱&#xff0c;我就告诉你我花了1天才偶然找到的内容哈哈&#xff0c;请留言

Thumbnail AI:让图片处理更智能

一、产品介绍 Thumbnail AI是一款基于人工智能技术的图片处理软件&#xff0c;能够快速、准确地生成各种尺寸的缩略图。这款软件非常适合用于网站建设、广告设计、电商等领域&#xff0c;能够大大提高图片处理效率。 二、应用场景 网站建设&#xff1a;在网站建设中&#xff…

在海绵城市建设中,低功耗遥测终端有哪些独特的优势?

近年来&#xff0c;随着物联网技术的迅猛发展&#xff0c;数据监测和传输已经成为各行各业不可或缺的环节。在诸多特殊环境中因供电问题、潮湿、不便进入等诸多原因&#xff0c;需要一款功耗低、数据传输稳定&#xff0c;防潮抗锈蚀的低功耗遥测终端。 为满足这一需求&#xf…

对谈美的:「速沸」心智如何成就爆款电火锅?

​ 「魔镜对谈」将不定期访谈行业大咖、品牌负责人&#xff0c;通过行业观察、用户分析、爆品拆解等内容分享富有价值的消费洞见。本期访谈魔镜邀请到美的生活电器事业部-调理电器总经理张进&#xff0c;为我们拆解美的电火锅如何洞察市场、通过「速沸」心智打造电火锅赛道爆品…

mysql清空并重置自动递增初始值

需求&#xff1a;当上新项目时&#xff0c;测试环境数据库导出来的表id字段一般都有很大的初始递增值了&#xff0c;需要重置一下 先上代码&#xff1a; -- 查看当前自动递增值 SHOW CREATE TABLE table_name; -- 重建自动递增索引&#xff08;可选&#xff09; ALTER TABLE t…

基于爬虫和Kettle的豆瓣电影的采集与预处理

一&#xff1a;爬虫 1、爬取的目标 将豆瓣电影网上的电影的基本信息&#xff0c;比如&#xff1a;电影名称、导演、电影类型、国家、上映年份、评分、评论人数爬取出来&#xff0c;并将爬取的结果放入csv文件中&#xff0c;方便存储。 2、网站结构 图1豆瓣网网站结构详…

数据聚合、自动补全、数据同步、es集群

目录 数据聚合 聚合的分类 DSL实现bucket聚合 DSL实现Metrics聚合 RestAPI实现聚合 多条件聚合 带过滤条件的聚合 自动补全 安装拼音分词器 自定义分词器 completion suggester查询 修改索引库数据结构 RestAPI实现自动补全查询 实现搜索框自动补全 数据同步 数…

Redis:原理速成+项目实战——Redis实战7(优惠券秒杀+细节解决超卖、一人一单问题)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理速成项目实战——Redis实战6&#xff08;封装缓存工具&#xff08;高级写法&#xff09;&&缓存总…

【IEEE会议征稿通知】第五届计算机视觉、图像与深度学习国际学术会议(CVIDL 2024)

第五届计算机视觉、图像与深度学习国际学术会议&#xff08;CVIDL 2024&#xff09; 2024 5th International Conference on Computer Vision, Image and Deep Learning 第五届计算机视觉、图像与深度学习国际学术会议&#xff08;CVIDL 2024&#xff09;定于2024年4月19-21日…

深度卷积神经网络

目录 1.AlexNet 2. 代码实现 1.AlexNet (1)特征提取 (2)选择核函数来计算相关性&#xff1a;怎么判断在高维空间里面两个点是如何相关的&#xff0c;如果是线性模型就是做内积。 (3)凸优化问题 (4)漂亮的定理 丢弃法的作用就是因为模型太大了&#xff0c;使用它来对模型做…

四、C++运算符(5)逻辑运算符

作用&#xff1a;用于根据表达式的值返回真值或假值 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> using namespace std; int main() {//逻辑运算符 非&#xff01;int a 10;int b 20;//在c中除了0都是真cout << !a << end…