当下的前端框架中,出现了一批以 rust 语言编写的编译和打包工具(如 rspack),在这之前还有一些以 golang 语言编写的打包工具(如 esbuild),这些相比于原生的使用 JavaScript 编写的打包工具(如 webpack)而言,他们的性能提升原因是什么?是因为语言层面的差异吗?
是的,编程语言上确切的提供了很大的差异化
编译型语言通常比解释型语言 (如 JavaScript) 拥有更好的性能,因为它们可以进行更深入的
优化和并行处理
编译过程中的优化
编译型语言在编译阶段可以进行大量的静态分析和优化,这些优化可以显著提高程序的执行效率,减少不必要的计算和内存访问包括:
- 函数内联优化
- 死代码消除
- 循环优化
- 内存分配优化等
函数内联优化
假设有一个函数 add(a, b) 用于计算两个数的和,在程序中被多次调用
编译器可以分析这个函数,发现它很小且没有副作用,就可以将函数调用处直接替换成函数体内的代码,从而省去了函数调用的开销
死代码消除
在一个程序中,有些变量或语句永远不会被执行到,编译器可以分析出这些 " 死代码 ",并将其从最终生成的机器码中移除。这样可以减小程序的体积,提高执行效率
循环优化
对于一个包含循环的代码段,编译器可以分析循环条件和循环体,进行各种变换和优化,比如: 循环展开、公共子表达式消除、向量化等,从而提高循环的执行效率
内存分配优化
编译器可以根据变量的作用域和生命周期,选择合适的内存分配策略,比如: 在栈上分配局部变量、重用内存空间等,减少内存占用和访问开销
机器码执行效率
编译型语言最终生成的是机器码,可以直接在 CPU 上执行,不需要再经过解释和中间代码生成等步骤
机器码的执行效率通常比解释型语言的中间代码或字节码高很多
并行处理能力
编译型语言通常可以充分利用多核 CPU 的并行处理能力,实现更高效的并发执行
这得益于编译器可以在编译阶段进行深入的分析和优化,识别出可以并行执行的部分。
语言特性支持
一些编译型语言本身就提供了丰富的并行编程特性,如线程、协程、任务等,方便开发者利用多核 CPU
全局解释器锁(GIL)
一些解释型语言(例如 Python)使用 GIL 来确保在任何给定时间只有一个线程执行 Python 字节码。这导致了解释器在多核处理器上无法实现真正的并行处理
虽然可以使用诸如多进程或异步编程等技术来绕过 GIL,但这增加了编程的复杂性