新 V8 即将推出和 Node.js

Node.js 就依赖于 V8 引擎, V8 引擎是由 Google 为 Chrome 浏览器编写的 JavaScript 虚拟机。从一开始,V8 的主要目标就是使 JavaScript 运行更加快速,或至少比竞争对手快。对于高度动态这并不容易。这部分是关于 V8 和 JS 引擎性能的演变。

V8 引擎的核心部分是能够高速执行 JavaScript 的 JIT(Just In Time)编译器。这是一个动态编译器,可以在运行时优化代码。当 V8 最初构建时,JIT 编译器被称为 FullCodegen。然后,V8 团队实现了 Crankshaft,其中包括许多 FullCodegen 未实现的性能优化。

从 90 年代开始,JavaScript 哪些操作快,哪些操作慢(无论引擎是什么)通常都是反直觉的,所以JavaScript 代码慢的原因常常难以理解。

近年来,Matteo Collina 和我专注于如何编写性能优异的 Node.js 代码。当然,这意味着当 V8 引擎执行代码时,要知道哪些方法是快速的,哪些方法很慢。

现在是我们挑战所有关于性能假设的时候了,因为 V8 团队已经编写了一个新的 JIT 编译器:Turbofan。

从常见的“V8杀手”开始,到更复杂的 Matteo 和我对 Crankshaft 性能的发现,我们将会根据一系列测试结果来对 V8 进行评估。

当然,在优化 V8 代码之前,我们应该首先关注 API 设计,算法和数据结构(过早的优化是万恶之源)。下面会对 Node 的几个版本进行性能测试。我们可以得到一些结论来影响我们的代码风格,以及在应用通常的优化后提高性能的方式。

Try / Catch 问题

一个非常出名的去优化模式是使用 try/catch blocks.

测试代码链接(https://github.com/davidmarkclements/v8-perf/blob/master/bench/try-catch.js) 分别测试如下 4 种情况

函数中有 try/catch
函数中不带 try/catch
在 try 中调用函数
调用函数(没有 try/catch)

测试数据

?

我们可以看到 node 6 ( V8 5.1 ) 中 try/catch 的性能问题确实存在,但在 node 8 到 node 8.2 得到明显的改善。

另外值得注意的是, 在 try block 中调用函数明显比在 try block 外面要慢。

到 node 8.3 以上的版本 try/catch 对调用函数的影响基本可以忽略不计。

删除对象的属性

由于 javascript 对象的动态特性和原型链,导致属性查找更加复杂。

这里使用 3 种方式删除对象属性(测试代码https://github.com/davidmarkclements/v8-perf/blob/master/bench/property-removal.js)。

通过设置直接给对象属性设为 undefined
通过 delete 删除属性
删除最近添加的属性

?

在 Turbofan (V8 6.0 and 6.1)可以发现删除最近添加属性的效率更高,通过给对象属性直接设为 undefined 的效率也是非常高的。而 delete 操作在大部分情况表现不佳。

Arguments

普通的 JavaScript 函数可用隐式参数对象,它很像数组。

为了使用数组方法或大多数数组行为,参数对象的索引属性已被复制到数组中。在过去,JavaScript 中人们倾向于将较少的代码等同于与较快的代码。虽然这个经验法则为浏览器端代码带来了有效负载的好处,但同样的规则导致了服务器端代码大小远不如其执行速度重要的痛苦。所以将参数对象转换为数组的一种简洁方法就变得非常受欢迎:

Array.prototype.slice.call(arguments)。这调用 Array slice 方法传递参数对象作为该方法的上下文,slice 方法会得到一个像数组一样的对象,并相应地执行。也就是说,它将整个参数array-like 对象作为一个数组。

但是,当函数的隐式参数对象从函数上下文中暴露出来(例如,当从函数返回或传递到另一个函数中时,如 Array.prototype.slice.call(arguments)所示),这通常会导致性能下降。

测试代码(https://github.com/davidmarkclements/v8-perf/blob/master/bench/arguments.js)

暴露 arguments 对象给其他的函数
使用 Array.prototype.slice 复制 arguments 对象
使用循环复制对象的每一个属性
使用 es6 的展开操作符

?

我们再把这些数据转化成折线图:

?

如果我们想要将函数输入的参数写成一个数组,在 Node 8.3 以上版本我们建议使用 spread 操作符。在 Node 8.2 及以下版本我们最好通过循环复制对象属性到一个新的数组以提升性能。

对于 node 8.3 及以上版本,将参数对象直接暴露给其他的函数的情况性能表现很不错,因此在不需要把参数写成数组,这种方式可以大大提升代码执行效率。

时间: 2024-10-10 02:43:26

新 V8 即将推出和 Node.js的相关文章

准备:新V8即将到来,Node.js的性能正在改变

V8的Turbofan的性能特点将如何对我们优化的方式产生影响 审阅:来自V8团队的Franziska Hinkelmann和Benedikt Meurer. **更新:Node.js 8.3.0已经发布了V8 6.0和Turbofan. Node.js依靠V8 JavaScript引擎来运行代码,其语言本身也是我们熟悉和喜爱的.V8 JavaScript引擎是Google为Chrome浏览器编写的JavaScript虚拟机.从一开始,V8的一个主要目标是让JavaScript运行地更快,或者至

node.js调试

不用每次都重启服务的supervisor 使用过PHP的同学肯定都清楚,修改了某个脚本文件后,只要刷新页面服务器就会加载新的内容,但是node.js在第一次引用到某个文件解析后会 将其放入内存,下次访问的时候直接在内存中获取,以提高效率,但是这对我们开发造成一定困扰,修改了某个module后只能重启服务器后才能生效,调试起 来效率还是很低的. 于是乎node.js中有了supervisor插件帮我们坚实文件改动,自动重启服务器,supervisor是node.js的一个包,安装起来很简单,使用n

node.js学习一——什么是node.js

定义:node.js是运行在服务器端的运用了谷歌v8引擎的javascript运行平台 特点:1. 异步式I/O(非阻塞式I/O) 2. 事件驱动 什么是异步式I/O(非阻塞式I/O)? 要了解什么是异步式I/O(非阻塞式I/O),必须要先了解下什么是I/O,什么阻塞, 什么是同步式I/O(阻塞式I/O). I/O的定义: 线程在执行磁盘读写或者是网络通信时统称为I/O操作. 阻塞定义: 在I/O的过程中由于要耗费的时间比较长,操作系统会剥夺这个线程对CPU的控制权,让线程暂停执行.同时把资源交

Node.js与io.js那些事儿

14年12月,多位重量级Node.js开发者不满Joyent对Node.js的管理,自立门户创建了io.js.io.js的发展速度非常快,先是于2015年1月份发布了1.0版本,并且很快就达到了2.0版本,社区非常活跃.而最近io.js社区又宣布,这两个项目将合并到Node基金会下,并暂时由“Node.js和io.js核心技术团队联合监督”运营.本文将聊一聊Node.js项目的一些历史情况,与io.js项目之间的恩怨纠葛,他们将来的发展去向.希望能从历史的层面去了解这个开源项目在运营模式上是如何

【读书笔记】《Node.js入门经典》

Node.js学习笔记 Nodejs学习笔记 Nodejs介绍 npmNode Package Manager 1 npm常用命令 IO的不可预测性 回调 1 回调剖析 2 Node在读写文件使用回调 3 Node在HTTP使用回调 4 回调顺序 5 同步与异步代码 HTTP 1 HTTP响应状态代码 2 使用URL模块响应不同的请求 3 使用Nodejs创建HTTP客户端 4 将函数发布为URL服务提供客户端接口 5 两个js文件相互调用函数 数据持久化 1 将数据写入文件 2 读取环境变量

Node.js与io.js的那些事儿

转自:http://www.infoq.com/cn/articles/node-js-and-io-js 去年12月,多位重量级Node.js开发者不满Joyent对Node.js的管理,自立门户创建了io.js.io.js的发展速度非常快,先是于2015年1月份发布了1.0版本,并且很快就达到了2.0版本,社区非常活跃.而最近io.js社区又宣布,这两个项目将合并到Node基金会下,并暂时由“Node.js和io.js核心技术团队联合监督”运营.本文将聊一聊Node.js项目的一些历史情况,

node.js内存缓存的性能情况

1. WEB 服务性能测试和优化 1.1   测试环境搭建 网络环境:内网 压力测试服务器: 服务器系统:Linux 2.6.18 服务器配置:Intel® Xeon™ CPU 3.40GHz 4 CPUS 内存:6GB 反向代理服务器:Nginx服务器 服务器系统:Linux 2.6.18 服务器配置:Pentium® Dual-Core CPU E5800 @ 3.20GHz 2CPUS 内存:2GB 发包服务器: 发包工具:apache 2.2.19自带的ab测试工具 服务器系统:Linu

Node.js+MongoDB+AngularJS Web开发

这篇是计算机类的优质预售推荐>>>><Node.js+MongoDB+AngularJS Web开发> MEAN全栈工程师首部实战书 从服务器到浏览器基于JavaScript的Web应用程序权威指南 内容完整细致可直接用来入门任一技术 编辑推荐 Node.js是一种领先的服务器端编程环境,MongoDB是最流行的NoSQL数据库,而AngularJS正迅速成为基于MVC的前端开发的领先框架.它们结合在一起使得Web程序员能够完全用JavaScript创建从服务器到客户端

你不知道的Node.js性能优化,读了之后水平直线上升

本文由云+社区发表 "当我第一次知道要这篇文章的时候,其实我是拒绝的,因为我觉得,你不能叫我写马上就写,我要有干货才行,写一些老生常谈的然后加上好多特技,那个 Node.js 性能啊好像 Duang~ 的一下就上去了,那读者一定会骂我,Node.js 根本没有这样搞性能优化的,都是假的." ------ 斯塔克·成龙·王 1.使用最新版本的 Node.js 仅仅是简单的升级 Node.js 版本就可以轻松地获得性能提升,因为几乎任何新版本的 Node.js 都会比老版本性能更好,为什么