从V8执行原理看为什么用TypeScript好

        众所周知,我们平常写的JavaScript 代码直接交给浏览器或者 Node 执行时,底层的 CPU 是不认识的,没法执行。而我们就需要使用JavaScript引擎对代码进行编译,JavaScript 引擎的主要功能,就是结合 JavaScript 语言的特性和本质来编译执行它。

         相信现在大部分前端用的都是V8引擎,也就是谷歌浏览器(Google)。V8 是由 Google 开发的开源 JavaScript 引擎,是 JavaScript 虚拟机的一种,模拟实际计算机各种功能来实现代码的编译和执行。我们可以简单地把 JavaScript 虚拟机理解成是一个翻译程序,将人类能够理解的 编程语言 JavaScript,翻译成机器能够理解的机器语言。

 

   V8是如何编译JavaScript代码的?

 

V8 执行一段 JavaScript 代码所经历的主要流程包括:

  • 初始化基础环境;

  • 解析源码生成 AST 和作用域;(Parser

  • 依据 AST 和作用域生成字节码;(Ignition)

  • 解释执行字节码;

  • 监听热点代码;(TurboFan)

  • 优化热点代码为二进制的机器代码;(TurboFan)

  • 反优化生成的二进制机器代码。

简单地说,Parser 将 JS 源码转换为 AST,然后 Ignition 将 AST 转换为 Bytecode,最后 TurboFan 将 Bytecode 转换为经过优化的 Machine Code(实际上是汇编代码)。

        如果函数没有被调用,则 V8 不会去编译它。

        如果函数只被调用 1 次,则 Ignition 将其编译 Bytecode 就直接解释执行了。TurboFan 不会进行优化编译,因为它需要 Ignition 收集函数执行时的类型信息。这就要求函数至少需要执行 1 次,TurboFan 才有可能进行优化编译。

        如果函数被调用多次,则它有可能会被识别为热点函数,且 Ignition 收集的类型信息证明可以进行优化编译的话,这时 TurboFan 则会将 Bytecode 编译为 Optimized Machine Code(已优化的机器码),以提高代码的执行性能

        图片中的红色虚线是逆向的,也就是说 Optimized Machine Code 会被还原为 Bytecode,这个过程叫做 Deoptimization。这是因为 Ignition 收集的信息可能是错误的。

function sum(a,b){
    return a+b
}

sum(1,2)
sum(2,3)
sum(3,4)
sum('1','2')

比如 sum 函数的参数之前是整数,多次调用后被识别为热点函数,后来又变成了字符串。生成的 Optimized Machine Code 已经假定 sum 函数的参数是整数,那当然是错误的,于是需要进行 Deoptimization(反优化)从而消耗性能。

TypeScript在参数上将函数明确规定类型后即可避免此类问题的发生,从而提高代码的执行性能。

我想应该也是使用TypeScript的好处之一。

    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值