上周,JavaScript 引擎「V8」的开发团队在该项目官方网站上正式宣布推出最新的 8.0 版本。这次更新的重点主要集中在错误修复及性能改善上,正式的版本将在数周后随着谷歌 Chrome 80 稳定版一起发布。

V8 是谷歌公司推出的开源高性能 JavaScript 引擎,主要用于提升 Web 浏览器内部 JavaScript 脚本执行的性能。V8 通过 C++ 语言编写,主要用在 Chrome 浏览器以及 Node.js 上,实现了对 ECMAScript 与 WebAssembly 的支持,可运行于 Windows 7、macOS 10.12 以及使用 x64、IA-32、ARM、MIPS 处理器的 Linux 系统,或更新版本的操作系统环境下。V8 既可以单独运行,也能够内嵌到任何基于 C++ 的应用中。V8 项目开发至今已拥有超过 11 年的历史。

性能

指针压缩

V8 引擎的这次更新,对内存占用量与速度都进行了优化。V8 堆包含了很多东西,例如浮点值、字符串字符、编译代码以及标定值,开发团队发现这些标记值占据了堆的很大一部分空间。

标定值与系统指针一样大,32 位宽度对应 32 位架构,64 位宽度对应 64 位架构。当开发团队对比 32 位版本与 64 位版本时发现,每个标记值使用了两倍的堆内存。

因为高位可以由低位合成,所以只需要将唯一的低位存储到堆中就能实现降低内存的占用量,平均可节省 40% 堆内存,这一方法被称为「指针压缩」。

通常情况下,在优化内存占用的同时也会牺牲部分性能,但经过这一改进之后,在 V8 及其垃圾收集器中却出现了真实网站的性能提升。

优化高阶内建

在优化高阶内建上,新版本解除了 TurboFan 优化流程中的一处限制,这处限制使高阶内建无法得到优化。

const charCodeAt = Function.prototype.call.bind(String.prototype.charCodeAt);

charCodeAt(string, 8);

到目前为止,对 charCodeAt 的调用对 TurboFan 来说是完全不透明的,从而引发了对用户定义函数通用调用。通过这一改变,现在可以识别出实际上是在调用内置 String.prototype.charCodeAt 函数,从而能够触发 TurboFan 库中的进一步优化来改善对内建的调用,进而获得与以下相同的性能:

string.charCodeAt(8);

这一变化也会影响到其他一些内建,比如 Function.prototype.apply、Reflect.apply,以及很多其他的高阶数组内建。

JavaScript

新版本在 JavaScript 方面出现了两个新特性 ── 可选链和 null 判断合并。

可选链

在编写属性访问链时,程序员经常需要检查中间值是否为空。没有经过错误检查的链可能会扔出,而经过了明确的错误检查的链是冗长的,并且会产生不必要的结果,即检查所有的真实值,而不是只检查非空值。

// Error prone-version, could throw.const nameLength = db.user.name.length;// Less error-prone, but harder to read.let nameLength;if (db && db.user && db.user.name)  nameLength = db.user.name.length;

可选链(?.)允许程序员编写更精炼、鲁棒性更强的属性访问链,检查中间值是否为空。如果中间值为空,则整个表达式的计算结果为未定义的。

// Still checks for errors and is much more readable.const nameLength = db?.user?.name?.length;

除了静态属性访问外,动态属性访问和调用也能得到支持。

null 合并

null 合并操作符 ?? 是一个新的用于处理默认值的短路二进制操作符。目前,默认值有时由逻辑 || 操作符处理,如下所示:

function Component(props) {  const enable = props.enabled || true;  // …}

对 || 的使用,并不适合计算默认值,因为当 a 为非真时 a || b 的结果为 b。如果 props.enabled 明确被设置为假,那么 enable 仍然为真。

通过 null 合并操作符,当 a 为空时,a ?? b 的结果为 b,否则结果为 a。这是理想的默认值行为,并使用 ?? 修正了之前提到的错误。

function Component(props) {  const enable = props.enabled ?? true;  // …}

null 合并操作符与可选链是相伴而生的特性,可协同工作。当没有任何 props 参数传入时,它们可以对示例进行进一步修改以作为应对。

function Component(props) {  const enable = props?.enabled ?? true;  // …}

V8 应用程序接口

请通过「git log branch-heads/7.9.. ..branch-heads/8.0 include/v8.h」指令来获得接口变化列表。

开发人员目前可通过指令「git checkout -b 8.0 -t branch-heads/8.0」来体验 V8 引擎 8.0 版本中的新特性。


相关项目地址:
高性能 JavaScript 引擎 V8 官方网站
高性能 JavaScript 引擎 V8 GitHub 地址

JavaScript 引擎「V8」发布 8.0 版本,内存占用量大幅下降的更多相关文章

  1. React + Node 单页应用「二」OAuth 2.0 授权认证 & GitHub 授权实践

    关于项目 项目地址 预览地址 记录最近做的一个 demo,前端使用 React,用 React Router 实现前端路由,Koa 2 搭建 API Server, 最后通过 Nginx 做请求转发. ...

  2. Slickflow.NET 开源工作流引擎基础介绍(九) -- .NET Core2.0 版本实现介绍

    前言:.NET Core 是.NET Framework的新一代版本,是微软开发的第一个跨平台 (Windows.Mac OSX.Linux) 的应用程序开发框架(Application Framew ...

  3. 「Vue」vue-cli 3.0集成sass/scss到vue项目

    vue-cli 3提供了两种方式集成sass/scss: 创建项目是选择预处理器sass手动安装sass-loader创建项目选择预处理器sass$ vue create vuedemo? Pleas ...

  4. 「Django」rest_framework学习系列-版本认证

    1.自己写: class UserView(APIView): versioning_class = ParamVersion def get(self,request,*args,**kwargs) ...

  5. V8 javascript 引擎

    V8是一个由丹麦Google开发的开源java script引擎,用于Google Chrome中.[2]Lars Bak是这个项目的组长.[3]   V8在执行之前将java script编译成了机 ...

  6. JavaScript 引擎 V8 执行流程概述

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/t__Jqzg1rbTlsCHXKMwh6A作者:赖勇高 本文主要讲解的是V8的技术,是V8的入 ...

  7. LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree

    2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  8. Node.js开源应用OSN发布初始V1.0版本-见面版本

    Nodejs开源应用OSN初始版本V1.0发布,请参考本操作说明文档,有任何问题请留言 Nodejs开源应用OSN发布V1.0版本: OSChina收录地址: OSC收录地址:http://www.o ...

  9. LibreOJ #2036. 「SHOI2015」自动刷题机

    #2036. 「SHOI2015」自动刷题机 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 题目描述 曾经发明了信号增幅仪的发明家 SHTSC 又公开 ...

随机推荐

  1. 密码学笔记——eval(function(p,a,c,k,e,d) 加密破解

    密码学笔记——eval(function(p,a,c,k,e,d) 的加密破解 例题: 小明某天在看js的时候,突然看到了这么一段代码,发现怎么也理不出代码逻辑,你能帮帮他吗? 格式:SimCTF{} ...

  2. 设备驱动基础学习--platform driver简单实现

    platform是一条虚拟的总线.设备用platform_device表示,驱动用platform_driver进行注册,Linux platform driver机制和传统的device drive ...

  3. C语言最重要的知识点(电子文档)

    总体上必须清楚的: 1)程序结构是三种:  顺序结构 .选择结构(分支结构).循环结构.  2)读程序都要从main()入口, 然后从最上面顺序往下读(碰到循环做循环,碰到选择做选择),有且只有一个m ...

  4. SVN代码迁移到GITlab

    ==================================================================================================== ...

  5. SniperOj-compare_flag-Writeup

    SniperOj-compare_flag-Writeup 题干如上,只给了一个nc命令,那么连接到服务器如下 有如下的python代码 #!/usr/bin/env python from time ...

  6. IQueryable、IEnumberable 、IList与List区别

    IEnumerable:使用的是LINQ to Object方式,它会将AsEnumerable()时对应的所有记录都先加载到内存,然后在此基础上再执行后来的Query IQeurable(IQuer ...

  7. Redis-消息

    Redis 发布订阅(实际开发不使用) Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. 下图 ...

  8. The Preliminary Contest for ICPC Asia Shanghai 2019 B Light bulbs (离散的差分)

    复杂度分析,询问一千次,区间长1e6,O(1e9)超时. 那么我们知道对于差分来说,没必要一个一个求,只需要知道区间长就可以了,所以我们定义结构体差分节点,一个头结点,一个尾节点. 这样tail.lo ...

  9. JAVA(2)之关于类的访问权限控制

    类的成员的四种访问权限 private 只能在当前类中访问 无修饰 同一个包中的类都可以访问 protected 同一个包中的类可以访问 不同包中的子类可以访问 public 所有类都可以访问 示例代 ...

  10. Go语言内置包之strconv

    文章引用自 Go语言内置包之strconv Go语言中strconv包实现了基本数据类型和其字符串表示的相互转换. strconv包 strconv包实现了基本数据类型与其字符串表示的转换,主要有以下 ...