写点什么

Rust 粉丝破大防!TypeScript 之父选 Go 语言重写编译器,性能飙升 10 倍引战:Rust 不香了?

  • 2025-03-13
    北京
  • 本文字数:4312 字

    阅读完需:约 14 分钟

大小:2.01M时长:11:41
Rust粉丝破大防!TypeScript之父选Go语言重写编译器,性能飙升10倍引战:Rust不香了?

微软已经着手将 TypeScript 编译器和工具集移植至 Go,旨在实现各类代码库的 10 倍编译速度提升。大部分开发者都觉得这是个好消息。不过,也有一些人感到不解,他们想知道,为什么微软选择了 Go 语言,而不是 Rust 语言来做这件事。

 

昨天,TypeScript 之父 Anders Hejlsberg 在一篇博文中宣布,微软已启动一项计划,将 TypeScript 编译器和工具移植至代号为“Corsa”的原生 Golang 实现。通过这次原生实现,微软承诺性能将提升 10 倍,同时增强开发者体验,并引入全新的 AI 驱动功能。

 

Hejlsberg 表示,这项工作还解决了大型代码库面临的扩展性挑战。TypeScript 用户目前在处理大型代码库时,往往面对加载时间过长、类型检查缓慢以及内存限制等问题,因此开发者被迫在合理的编辑器启动时间和获取源代码完整视图之间做出选择。

 

现在,通过将 TypeScript 编译器移植到 Go 语言,微软不仅提升了性能,还有效应对了扩展性挑战。

 

向 Go 迁移,获得 10 倍提升

 

关键性能提升包括:构建时间缩短约 10 倍,项目加载速度提升 8 倍,内存占用减少至当前实现的大约一半(预计未来还将进一步优化)。此外,语言服务方面也有显著改进,补全、快速信息(quick info)、跳转到定义以及查找所有引用的速度均大幅提升。

 

“原生实现将显著加快编辑器启动速度,使大多数构建时间缩短 10 倍,并大幅降低内存占用。”Hejlsberg 写道。

 

新的原生版本在多个热门代码库上展现出了卓越的性能指标:

  • VS Code (1,505,000 LOC): 77.8s → 7.5s(提升 10.4 倍)

  • Playwright (356,000 LOC): 11.1s → 1.1s(提升 10.1 倍)

  • TypeORM (270,000 LOC): 17.5s → 1.3s(提升 13.5 倍)

  • date-fns (104,000 LOC): 6.5s → 0.7s(提升 9.5 倍)

  • tRPC (18,000 LOC): 5.5s → 0.6s(提升 9.1 倍)

  • rxjs (2,100 LOC): 1.1s → 0.1s(提升 11.0 倍)

 

性能提升 10 倍,这不仅仅是数字上的变化,它意味着 TypeScript 和 JavaScript 的开发体验迎来了巨大飞跃。

 

以编辑器为例,大多数开发者的工作时间几乎都在编辑器中度过,因此编辑器的性能至关重要。理想情况下,它应能快速加载大型项目,并在各种操作中保持流畅响应。而编辑器的核心性能很大程度上取决于底层语言服务的速度。借助原生实现,TypeScript 的编辑体验达到了前所未有的流畅度。

 

为了更具体地说明这一点,以 Visual Studio Code 代码库为例,目前在高配置计算机上将完整项目加载至编辑器中的用时约为 9.6 秒。而使用原生语言服务之后,加载时间缩短至 1.2 秒左右,提升约 8 倍。

 

在解释为何要更换语言时,Hejlsberg 指出,JavaScript(TypeScript 所基于的语言)主要用于 UI 和浏览器场景,而并不适用于编译器或系统级工具等计算密集型工作负载。他补充道,微软可能已经接近 JavaScript 性能优化的极限,“我们能从 JavaScript 中榨取的性能提升空间已经所剩无几。”

 

在开发策略方面, Hejlsberg 表示,他们的团队明确希望对 TypeScript 编译器进行移植(port),而不是完全重写(rewrite)成 Go。

 

在 TypeScript 项目的常见问题解答(FAQ)中,TypeScript 团队的开发负责人 Ryan Cavanaugh 进一步解释说,在更换编程语言时,通常有两种策略可选。一是重写(rewrite), 从零开始实现一个新的系统,目标是解决与原系统相同的问题,但不考虑原有代码库的实现方式。二是移植(port),以现有代码库为基础,将其转换为新的语言,同时尽可能保持原有架构和逻辑不变。而移植的执行速度更快,但前提是新语言在架构上与原语言至少有一定的兼容性。

 

Hejlsberg 表示,微软曾尝试用 C#、C++、Rust 等常见候选语言进行原型开发,但最终发现 Go 最适合他们的特定工作负载。

 

Arcjet CEO David Mytton 在接受媒体采访时表示:

“非常有趣!JS 开发者早已习惯了慢速的工具,因此一个能加快编辑器启动时间的高速编译器无疑是个好消息。迁移到原生编译器是合理的选择,尽管 Go 作为这一类项目的实现语言有些不太常见。看到这个公告时,我本以为他们会像其他 JS 工具重写项目那样选择 Rust,比如 Rolldown、Turbo(从 Go 迁移到 Rust)、Deno……我很好奇他们做出这一决策的原因。” (编者注:此外还有个 SWC,一个用 Rust 编写的 TypeScript/JavaScript 编译器,被 Next.js、Parcel、Deno、Vite 等工具采用。)

 

对于这个问题,Cavanaugh 在 FAQ 中回应称,考虑到多个特定因素,Go 仍然是最优选择。

“最关键的一点是,我们需要尽可能保持新代码库的兼容性,无论是在语义层面还是代码结构上。” 他写道,“我们预计未来相当长一段时间内会同时维护两个代码库,因此能够保持结构相似的语言对于代码迁移和维护极为有利,因为这样我们可以更轻松地在两个代码库之间同步变更……”

 

基于 Go 的 TypeScript 实现现已在 GitHub(https://github.com/microsoft/typescript-go)开源,并已能够加载多个主流 TypeScript 项目,包括 TypeScript 编译器自身。

 

Rust 粉丝震惊:为何没有选择 Rust?!

 

有网友好奇,微软 TypeScript 团队在最终选择 Go 语言之前,到底尝试了 Rust 多久?毕竟 Rust 以性能和安全性著称。有人调侃说:“我听说他们几乎撑过了午饭时间才换的。” 这句话可能暗示 TypeScript 团队并没有对 Rust 进行深入的尝试。

 


事实上,不少人对此决定感到不解,他们想知道,为何微软最终没选 Rust。这种疑惑和不解的情绪,在社交媒体上尤为明显。正如一位 X 网友所言:“比 TypeScript 实现 10 倍提速更令人震惊的是,他们竟然没有选择 Rust。”

 


另一位用户更是直言,“转眼间,Java 与 C# 谁更好的战火就蔓延到了 Rust 和 Go 这边。感谢 TypeScript 煽动了这场纷争。”

 


显然,TypeScript 团队的选择在开发者社区中引发了关于编程语言选择的激烈讨论。更有甚者,有用户以幽默的方式表达了对 Rust 拥趸的看法,“为什么 Rust 狂热者在 TypeScript 选择 Go 重写编译器时哭泣?因为他们无法接受 Go 在不需要生命周期保证的情况下也能抢走风头!”

 


随着不满情绪的出现,TypeScript 首席开发者 Ryan Cavanaugh 出面做出澄清,承认他们已经预料到开发者社区就会此展开争论。

 

他提到,虽然 Rust 也是个不错的选择,但“决定性因素”在于可移植性,即如何确保新代码库在算法上与当前代码库保持一致。

 

他还透露,TypeScript 团队探索了多种方法来表示代码,检验用 Rust 重写代码是否可行。但其在性能和开发体验等方面带来了“不可接受的”问题。某些方案需要单独实现垃圾收集器(GC),这会增加额外的复杂性。

 

与之形成鲜明对比的是,Go 语言具备内存自动回收机制,即所谓“垃圾收集”。Cavanaugh 坦言,“虽然二者中的某些机制相当接近,但 Rust 往往需要使用大量不安全代码,而且 Rust 似乎缺少充足的原语组合来实现有益于开发者体验的 JavaScript 代码移植目标。”

 

他解释称,团队最终面临着两个选项。要么使用 Rust 从头开始重写,而这可能需要耗费“数年时间”,并最终产生一个“没人愿意用”的 TypeScript 版本;要么在一年之内用 Go 构建一个可用的移植版本,在语义方面“高度”兼容,同时提供具有竞争力的性能表现。

 

Cavanaugh 同时强调,Go 与 Rust 一样,都具备出色的代码生成、数据表示能力和“强大的”并发原语。就设计目标而言,Rust 的表现也算相当出色,但“将特定 JavaScript 代码库直接移植为 Rust”则并不贴合这款编程语言的设计特性。

 

他承认,Go 其实也有类似的问题,但结合此前 TypeScript 的代码编写方式,Go 出人意料地非常适合这项移植任务。

 

他在 GitHub 上的一篇帖子中补充道,“我们还有大量图形处理任务,特别是涉及多态节点的向上与向下遍历树。Go 在处理这些工作时仍可提供良好的开发者体验,特别是在处理 JavaScript 版本代码方面尤其突出。”

 


在接受采访时,TypeScript 首席架构师 Anders Hejlsberg 也基本重申了 Cavanaugh 的观点。

他提到,该项目的核心意义所在,就是要按原本移植现有代码库。原始代码库是根据某些假设条件设计而成——其中最重要的一点,就是必须存在自动垃圾收集机制。

 

Hejlsberg 表示,“可以说这限制了我们的选择范围,也让 Rust 基本退出了决赛圈”,这里指的当然是 Rust 缺少自动内存管理。

 


原始 TypeScript 与移植后的 Go 代码仍高度相似。

 

正如 Hejlsberg 的解释,Rust 面对的另一个挑战,是它对循环数据结构做出了严格限制,而 TypeScript 编译器高度依赖循环数据结构。该系统包含具有父子引用的抽象语法树(AST)、相互引用的符号与声明,以及自然形成循环的递归类型。

 

“这些问题的存在,使得原生代码的迁移工作变得极其困难。”Hejlsberg 还解释道,考虑到这种种需求,Go 最终脱颖而出、成为最合适的选项。

 

值得注意的是,TypeScript 建立在 JavaScript 之上。“如果大家经常使用 JavaScript,就知道向 Go 迁移比向 Rust 迁移要简单得多。”

 

Hejlsberg 还表示,这样的 Go 转换对于系统的影响也非常温和,毕竟其并不是那种强调繁文缛节的“特别复杂”的语言,“而 Rust 则恰恰相反”。

 

未来规划

 

微软预计将在 2025 年年中推出具备命令行类型检查功能的原生 tsc 预览版(tsc 即 TypeScript 编译器)。到 2025 年底,项目构建和语言服务的完整实现版本有望发布。目前最新的 TypeScript 版本是 TypeScript 5.8,TypeScript 5.9 也即将发布。JS 版本的代码库仍将持续开发,进入 6.x 版本系列。同时,TypeScript 6.0 将引入部分废弃特性和破坏性变更,以便与即将推出的原生代码库保持一致,Hejlsberg 透露。

 

“当原生代码库与当前 TypeScript 版本达到足够的功能对等时,我们将正式发布 TypeScript 7.0。”

 

此外,Hejlsberg 进一步解释道: “为了便于区分,我们会直接将它们称为 TypeScript 6(JS 版本)和 TypeScript 7(原生版本),这一命名方式将在可预见的未来保持不变。

在内部讨论或代码注释中,你可能还会看到 ‘Strada’(TypeScript 的原始代号)和 ‘Corsa’(此次原生迁移的代号)这两个名称。”

 

与此同时,除了速度提升,原生版本还带来了额外的优势,包括:即时、全面的错误列表,覆盖整个项目;更高级的重构能力;更深入的代码分析,此前由于计算成本过高而难以实现;同时为下一代 AI 赋能开发工具奠定基础。微软还计划迁移至 Language Server Protocol(LSP),以更好地对齐其他编程语言的开发体验。

 

“TypeScript 的核心价值主张是提供卓越的开发体验。” Hejlsberg 写道,“随着代码库规模的增长,TypeScript 的价值也在提升。但在许多情况下,它仍难以扩展到超大规模代码库。”

 

参考链接:

https://devblogs.microsoft.com/typescript/typescript-native-port/

https://github.com/microsoft/typescript-go/discussions/411

https://thenewstack.io/go-power-microsofts-bold-bet-on-faster-typescript-tools/

https://www.youtube.com/watch?v=10qowKUW82U&t=755s

2025-03-13 17:529192

评论 1 条评论

发布
用户头像
是的
2025-06-19 07:16 · 广东
回复
没有更多了

Kafka.07 - 性能优化介绍

insight

kafka 2月春节不断更

产品0期 - 第五周作业

曾烧麦

产品训练营

处理XML数据应用实践

华为云开发者联盟

xml 数据库 数据 XML文档 GaussDB(DWS)

基于matlab的控制系统与仿真4-判断系统稳定性

AXYZdong

matlab 2月春节不断更

云原生2.0时代:企业更应了解一下容器安全

华为云开发者联盟

容器 云原生 安全 漏洞

话题讨论 | 在中国程序员工作是青春饭吗?

happlyfox

话题讨论 2月春节不断更 话题王者

厘清 I/O 模型

sakila

网络编程 I/O

谁手握账本?趣讲 ZK 的内存模型

HelloGitHub

Java zookeeper ZooKeeper原理

揭开《钢铁侠》AI管家贾维斯神秘面纱的扛鼎之作!

博文视点Broadview

揭秘京东城市时空数据引擎—JUST如何助力交通流量预测

京东科技开发者

JUST 流量预测

高手来啦!十八般武艺保护你的Web应用

云计算

Centos7配置librdkafka运行时

happlyfox

Centos 7 28天写作 2月春节不断更

第一篇文章

棉花糖

【LeetCode】转置矩阵Java题解

Albert

算法 LeetCode 28天写作 2月春节不断更

可能是Java Stream的最佳实践(二)

ES_her0

28天写作

魔改出一个 Encoder | Rust 学习笔记(一)

李大狗

区块链 rust 入门

技术干货 | 中间件技术在百度云原生测试中的应用实践

百度开发者中心

底层技术 #技术干货#

Oracle sqlldr快速导入和sqluldr2快速导出

阳光下、慵懒的熊

数据库

LeetCode题解:718. 最长重复子数组,动态规划,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

开工来面试了几十个人,一言难尽

yes

面试

工作日志2-23

技术骨干

批量下载,我有妙解~

Viktor

JavaScript iframe 跨域

新思科技静态应用安全测试帮助Cryptsoft公司提高软件安全和质量水平

InfoQ_434670063458

技术干货 | 趣谈哈希表优化:从规避 Hash 冲突到利⽤ Hash 冲突

百度开发者中心

算法 数据结构和算法

程序员成长第十二篇:做好项目计划

石云升

项目管理 程序员 28天写作 2月春节不断更

Linux 入门篇 —— 重定向与管道符

若尘

Linux 管道符 linux开发

教你如何在Python中读,写和解析CSV文

华为云开发者联盟

Python csv

华为云“网红”语言Python课程来啦!

华为云开发者联盟

Python

腾讯位置服务开发应用

我是哪吒

28天写作 2月春节不断更 腾讯地图 腾讯位置服务开发应用 腾讯位置

使用Kong作为微服务网关

行者AI

kong

【文末彩蛋】数据仓库服务 GaussDB(DWS)单点性能案例集锦

华为云开发者联盟

sql 数据仓库 数据

Rust粉丝破大防!TypeScript之父选Go语言重写编译器,性能飙升10倍引战:Rust不香了?_性能优化_Tina_InfoQ精选文章