持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
ignation模块(解释器/转化器)
作用:将ast抽象语法树转换成字节码(bytecode) 如果函数未调用,是不会转换成ast的
疑惑:为什么不直接转换成机器码呢?
因为当前程序运行环境可能不一样的,可能跑在mac本的Chrome浏览器上,也有可能跑在window本的Chrome浏览器上,也有可能跑在服务器linux的电脑的浏览器或node上,不同的环境有不同的cpu,不同的cpu可能又有不同的架构,不同的架构所执行的机器指令是不一样的(就不深入了,没实力)
解惑:由于存在环境可能不一样,所以很难知道到底转换成哪种机器指令(和java很像),所以这里将我们的代码转换成字节码(可以实现跨平台)
当要运行的时候,V8引擎会将字节码转换成对应的机器指令,字节码转换成机器码肯定比ast抽象语法树转换成字节码性能要好
字节码 ===> 汇编代码 ===> cpu要执行的机器指令
等等,还没完,还漏了一个TurboFan模块
TurboFan模块
觉不觉得字节码转换成cpu对应的机器指令也很费性能,比如一个函数,多次调用,我就要多次转换,一样的工作,重复执行,所以,TurboFan模块就来解决问题了
如何解决:
将我们多次调用的函数直接从字节码转换成对应的cpu机器指令并保存起来,等到被调用时直接执行指令,性能直接拉满(只执行少次的代码就不用进行转化了,浪费空间资源)
那么问题来了,它怎么知道这个函数被多次执行了?
是由ignation模块来进行收集信息,比如函数的执行信息,如果发现函数执行评频率非常高,就会把这个函数进行标记成hot(热函数),一旦是热函数就会由TurboFan模块进行转换成优化后机器指令(MachineCode)
不过这样还是有问题的
比如说这个函数是求和函数
function sum(num1, num2) {
return num1 + num2
}
sum(20, 20)
sum(30, 30)
......
sum('20', 30)
本来是数字相加的,突然传来了一个字符串,字符串和数字相加是不同的指令的,又由于JavaScript是一门动态语言,不会对类型做检测,所以一开始是检测不到数据类型的变化的,导致最后那个字符串类型函数运行时机器指令不能用,就会通过Deoptimizayion(反向优化),把机器指令转换成字节码,在按照字节码的方式进行运行结果,
所以TypeScript代码比我们平时写的JavaScript代码性能稍微高一点