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

转载于:https://www.cnblogs.com/fenglee/p/7340580.html

新 V8 即将推出和 Node.js相关推荐

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

    V8的Turbofan的性能特点将如何对我们优化的方式产生影响 审阅:来自V8团队的Franziska Hinkelmann和Benedikt Meurer. **更新:Node.js 8.3.0已经 ...

  2. JavaScript新发展 CoffeeScript Dart Rust Node.js

    CoffeeScript http://coffeescript.org/ CoffeeScript (GitHub repo) 是一个使用纯Ruby编写的新编程语言,创建者 Jeremy Ashke ...

  3. Node.js 内存管理和 V8 垃圾回收机制

    作者:五月君 链接:https://www.imooc.com/article/288799 来源:首发慕课网 本文已获作者 "五月君" 授权转载,原文首发于 "慕课网& ...

  4. 【全文】狼叔:如何正确的学习Node.js

    说明 2017-12-14 我发了一篇文章<没用过Node.js,就别瞎逼逼>是因为有人在知乎上黑Node.js.那篇文章的反响还是相当不错的,甚至连著名的hax贺老都很认同,下班时读那篇 ...

  5. 狼叔:如何正确的学习Node.js

    1. [知乎Live]狼叔:如何正确的学习Node.js 预览地址 i5ting.github.io/How-to-lear- Live 简介 你好,我是 i5ting ,江湖人称「狼叔」,目前是阿里 ...

  6. 【全文】狼叔:如何正确的学习Node.js 1

    说明 2017-12-14 我发了一篇文章<没用过Node.js,就别瞎逼逼>是因为有人在知乎上黑Node.js.那篇文章的反响还是相当不错的,甚至连著名的hax贺老都很认同,下班时读那篇 ...

  7. Node.js 笔记01

    一.Node.js 前言 1.node.js 之父 Ryan Dahl(瑞安达尔) ,技术好,颜值高! 数学系博士, 中途退学, 为了生活, 学习了Ruby On Rails接Web项目, 经过两年成 ...

  8. node.js使用手册_权威的Node.js手册

    node.js使用手册 Note: you can get a PDF, ePub, or Mobi version of this handbook for easier reference, or ...

  9. node.js在注册表删除_Node.JS 11年:时间表和重要贡献

    node.js在注册表删除 Do you know 你知道吗 Node.js在2020年5月27日已满11岁 (Node.js has turned 11 on 27th May 2020) ? Ca ...

最新文章

  1. 一文彻底理解Java单元测试
  2. 本地化中文示例代码需求调查
  3. Error: Could not find or load main class org.apache.tez.dag.app.DAGAppMaster
  4. Qt使用invokeMethod反射机制实现进程间的通信
  5. Qt工作笔记-三种方式解决Qt5中文编码问题
  6. python初始环境安装
  7. 11.11 双十一 前端教你一键领取天猫千张优惠券 (领前先想想有没有钱花这些优惠券)...
  8. ESLint规则配置说明
  9. Python环境搭建教程
  10. 关于利用DEM生成水系图
  11. Xmind8 思维导图
  12. 经理人必看的十个管理网站
  13. 去马赛克的频域方法(可抗混叠)
  14. 以太网结构框架的学习
  15. 在Linux系统中安装JDK
  16. Python 绘制游戏窗口
  17. 数据清洗-使用es的ingest
  18. SCARA四轴机器人eye-to-hand手眼标定(九点标定)
  19. Android项目---快递查询
  20. 一本书读懂财报 | 资产负债表剖析

热门文章

  1. asp.net获取浏览器的唯一标识_vue单页面应用如何在微信浏览器里进行网页授权获取用户信息
  2. php-fpm安装包_linux下安装php php-fpm(转载)
  3. 用python处理excel表格_使用Python处理excel表格(openpyxl)及表格中的中文处理
  4. lisp语言代替python_Lisp 语言优点那么多,为什么国内很少运用?
  5. postman测试websocket_还在手工写接口测试文档,已经out了
  6. python命令行参数 空格_Python 命令行参数
  7. 人脸对齐(十二)--PIFA2017
  8. SpringBoot+Swagger2
  9. c语言else不运行,if...else if..else第三句不执行?
  10. Spark sample入门到精通