JavaScript为什么快--第三篇

简介: 原视频上一篇文章JavaScript 为什么快--第二篇讲到,抽象语法树(Abstract Syntax Tree,AST)生成字节码。本篇文章将延续字节码后的,JavaScript代码是如何执行的。

原视频

上一篇文章JavaScript 为什么快--第二篇讲到,抽象语法树(Abstract Syntax Tree,AST)生成字节码。本篇文章将延续字节码后的,JavaScript代码是如何执行的。
How JavaScript Engines Work by Franziska Hinkelmann @ Web Rebels 2017
JS引擎渲染逻辑图_jpeg

结论先行

我们以前看到的优化建议,对V8而言,很可惜这些经验逐渐都没用了。
Avoid keywords(eval, try-catch, ...) not useful anymore.

经验之谈的优化点,对于日益精进的V8来说并不可靠,最可靠的优化是”静态类型“
Write code that looks "statically typed"

JavaScript引擎使用runtime时采集的类型信息,优化提速。所以虽然JavaScript虽然是动态类型的语言,但我们要尽可能的写静态类型的代码。

另外目前和热门的WebAssembly也使用TurboFan优化代码。

JavaScript引擎有哪些?

  • 浏览器:V8, Chakra, JavaScriptCore, SpiderMonkey
  • Node.js:V8, Chakra, SpiderNode
  • Electron: V8
  • IoT: Duktape, JerryScript

JavaScript背景

JavaScript实现EcmaScript标准,由TC39制定。正是这个标准,导致JavaScript无论是哪个JS引擎实现,都需要考虑一堆的类型判断。例如类型转化的定义:https://www.ecma-international.org/ecma-262/9.0/index.html#sec-type-conversion

JavaScript一个很吸引人的特性就是:动态类型语言(var定义变量),C++是静态类型语言。而JS引擎也是C++实现的,所以对于引擎开发者来说还是需要考虑将JS的变量转换为静态类型。

为了快速解析并运行JavaScript脚本,V8引入了JIT,快速解析出字节码,由基线编译器生成"粗糙"的机器码去执行,这样实现了快速执行。
但是后果就是这些基线代码效率很低,因为Ecma的标准中有大量的歧义和类型判定。
所以V8又引入了优化编译器,将经常执行的”hot“函数优化机器码提升,这些函数的执行效率。

注释:Just In Time(JIT) Compilation
Generate machine code during runtime, not ahead of time(AOT)

JS引擎渲染单元逻辑

JS引擎渲染单元名称

基线编译器

将字节码转化成基线机器码,去执行。并且将经常执行的”hot“函数,发给优化编译器,生成优化后的函数机器码提效。

优化编译器

re-compoile, 使用之前执行的类型信息优化,重新编译”hot“函数。(所以不要改变类型!!!)
de-compile, 一旦类型改变,就会失效,就会跌回baseline,重新优化。

优化点:永远构造相同类型的对象:

//举个栗子
function load(obj) {
    return obj.x;
}
load({x:4, a: 1});
load({x:4, a: 2});
load({x:4, a: 3});
load({x:4, b: 1});//这里会触发de-compile
//我们应该这样使用:
load({x: 4, a: 7, b: undefined, c: undefined});
load({x: 4, a: undefined, b: 1, c: undefined});
load({x: 4, a: undefined, b: undefined, c: 3});

JS引擎渲染DeCompile逻辑

//举个栗子
function add(obj) {
  return 1+obj.x;//JavaScript 中"+"号的复杂定义;obj.x的Property lookup
}
add({x:7});//+ operator according to spec(slow)
add({x:42});
...
add({x:123});//"hot",they "always integers",fast code for integer addition(fast);
add({x:'Hello;}); //"hot" failed, + operator according to spec(slow)

V8中的类型比较:HaveSameMap

Shape of object = map = hidden class

var obj1 = {x:5};
var obj2 = {x:17};
console.log(%HaveSameMap(obj1, obj2));

可以用V8参数开启这个内置C函数来检查2个Object是否一致:$ node --allow-natives-syntax maps.js

目录
相关文章
|
Web App开发 JavaScript 前端开发
JavaScript为什么快--第一篇?
V8让JavaScript更快的秘密;V8的JavaScript执行管道;TurboFan&Ignition
2788 0
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的个人健康管理系统小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的个人健康管理系统小程序附带文章源码部署视频讲解等
11 2
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的高校宿舍信息管理系统小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的高校宿舍信息管理系统小程序附带文章源码部署视频讲解等
8 1
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的电影交流平台小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的电影交流平台小程序附带文章源码部署视频讲解等
10 1
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的电器维修系统小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的电器维修系统小程序附带文章源码部署视频讲解等
8 1
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的大学生校园兼职微信小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的大学生校园兼职微信小程序附带文章源码部署视频讲解等
12 1
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的二手物品交易平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的二手物品交易平台附带文章源码部署视频讲解等
10 1
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的机电公司管理信息系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的机电公司管理信息系统附带文章源码部署视频讲解等
10 0
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的汉中茗茶微系统设计与实现附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的汉中茗茶微系统设计与实现附带文章源码部署视频讲解等
9 0
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的贵工程寝室快修小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的贵工程寝室快修小程序附带文章源码部署视频讲解等
9 0