TypeScript 语言在不改变算法复杂度前提下,细节上性能优化,运行时性能提升效果明显吗?

有经验的专家写的代码,和无经验的新手写的代码,在运行时性能上大概会有多少差异?
个人感觉,常规业务逻辑代码通常可以差 1 倍;如果算上框架的影响,可以差 2~4 倍。

仅考虑业务代码的话,新手容易搞不清楚 Control Flow 进而绕了一大圈去完成原本可以直接完成的事情。我在优化或者重构过程中需要花费很大的精力去梳理原先的 Control Flow,这部分优化已经可以带来将近成倍的提升,例如:

  • 将串行网络请求修改为并行
  • 添加一些缓存(如 React.memo
  • 把会导致 UI 重渲染的代码整合在一起,做批处理

细化到核心算法层面,我的思路是:算法剪枝 + 围绕引擎的优化(主要是 V8)。剪枝就得根据具体算法来看了,剪得好也能得到将近成倍的提升,也不属于本问讨论范围。

以各位专家(我不是)的经验,这种编译器最多可以提升多少% 运行时性能?可以推荐一下该款编译器的主要优化方向吗?

围绕引擎的优化我认为是有可以做的空间的。例如:

  • Map<string, T> 重构为 Record<string, T | undefined>,读取速度可以快 30% 左右,修改删除速度不清楚
  • forEach(fn) 重构为 for (let i = 0; i < arr.length; i++) 循环自身开销可以减少 20% 左右
  • function foo(...args: T[]) 重构为 function foo(args: T[]),可变参数改固定参数,会有一定的提升
  • class 属性 [[Define]] 语义改为 [[Assignment]] 语义,现有情况下可以提升 50% 左右的实例化性能
  • class 中 foo?: T 重构为 foo: T | undefined,提前初始化所有属性(即使是没用到的属性,也初始化为 undefined)会有一些函数字节码缓存相关的调用性能提升 [1]
  • 为了传参创建一次性对象,改为固定使用一个对象不断改变其值,可以减少 GC 稳帧率
  • 强制整型运算,例如 1 + 1 重构为 (1 | 0) + (1 | 0)
  • ……肯定还有很多我不知道的

注:以上数字偷个懒没考证,可以再用 https://jsbench.me/ 跑一下

值得一提的是,若干年前,emscripten 和 asm.js 应该使用了非常多的奇技淫巧,来把 C++ 代码变成高性能的 JS 代码,到现在应该都还有参考价值。

但是按我的经验来看,业务代码可能绝大多数都是 IO 密集型的,引擎级别的优化能让业务代码提升多少,真的不好回答。如果是计算密集型的库代码,综合提升 10%~20% 应该是有希望的。

说完了可能的方向,我来说一个我认为通过编译器优化 TS 代码的一些潜在困难

  1. 大部分 JS 开发者没有类型意识,甚至有一小部分开发者认为类型是写代码过程中的累赘。由此产生的问题有:代码中经常出现 any 或者跟 any 极为相似的类型,相当于是完全关闭了类型系统,难以优化;空值问题显著,例如很多开发者并不知道 foo?: Tfoo: T | undefinedfoo: T | nullfoo: T | null | undefined 到底有什么区别。
  2. TS 无任何运行时束缚,而且 TS 就是这么设计的。因此,万一编译器把类型搞错了,不会有任何提示,只会有线上 Bug。
  3. TS 在一些情况下 unsound,这是为了妥协 JS 社区中一些常见用法而设计的,降低了类型系统的门槛,但可能对编译器不友好。

当然相信在巨佬的努力下是可以解决这些难题的~

最后夹带一个性能优化万金油,没试过的甚至可能直接完成你下半年的性能优化 OKR

在项目中用了各种转码器(babel、esbuild、swc)的同学,转码器虽好,但他们都是有性能代价的。把向下兼容的版本调的越低,兼容代码给业务代码带来的性能负担就会越重,包括运行效率和包体积。

用 babel-preset-env 的,开启 loose 选项,整个项目可以加速 10%~30%。如果写的是库,可以配合 esbuild/swc + buble(不是 typo,真的叫 buble,但已经不维护了,慎用),几乎可以做到 0 编译开销。

Reference
[1] https://stackoverflow.com/questions/44466931/is-it-an-optimization-to-explicitly-initialize-undefined-object-members-in-javas

image.png

image.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值