微软用 Go 重写 TypeScript

mainjzb · 2025-3-12 10:14:29 · 1777 次点击

发现前一个帖子的大部分并没有看到视频内容,发现这个英文帖子把视频内容很好的截取出来,包含大部分人争议的议题

翻译自: https://www.reddit.com/r/golang/comments/1j8shzb/comment/mh8khdw

当你观看对 Anders Hejlsberg ( TypeScript 的创建者)的采访时,选择 Go 的原因其实很有道理。

从视频中可以得知: https://www.youtube.com/watch?v=10qowKUW82U

[08:58] "当我们意识到这可以提速 10 倍!"

Anders: 8 月份,我开始移植扫描器和解析器,只是为了获得一个测试结果,测试这样做我们可以有多快,以及从 JavaScript 移植到 Go 有多难。它实际上进展得很好,在几个月内,我们有了一个可以运行的东西,可以解析我们所有的源代码,没有错误,我们可以从中推断出一些数字。就在那时,我们开始意识到,“好吧,我们可以用这个达到 10 倍”,因为我们从原生程序中得了大约 3 倍-3.5 倍的速度,然后我们从并发中获得了另外 3 倍-3.5 倍的速度。总的来说,这让我们达到了 10 倍——而 10 倍是相当戏剧性的。

[12:34] 为什么不是 Rust?

Anders: 当你有一个已经使用了十多年的产品,有数百万程序员,天知道有多少数百万行代码,你将面临你能想象到的最长的不兼容问题。因此,从一开始,我们就知道,只有移植现有的代码库,这才有意义。现有的代码库做出了某些假设——具体来说,它假设有自动垃圾收集——这几乎限制了我们的选择。这严重排除了 Rust 。我的意思是,在 Rust 中,你有内存管理,但它不是自动的;你可以进行引用计数或其他任何可能的操作,但除此之外,还有借用检查器,以及它对数据结构所有权施加的相当严格的限制。特别是,它有效地取缔了循环数据结构,我们所有的数据结构都是严重循环的。

[16:29] 把这些都加起来:Go 很有意义

Anders: 当我们按照这个列表继续下去的时候,我们需要一种能够在所有主要平台上为我们提供优秀的优化原生代码的语言。我们想要一种语言,在数据结构中有很强的表达能力,允许循环数据结构,但也允许像 structs 这样的内联数据结构。所以,你知道在 JavaScript 中,你对一个对象所做的一切都是一种分配,我们宁愿避免这种情况,特别是对于小对象,如果我们可以将它们内联存储。我们需要自动垃圾收集,还需要并发性 —— 以及共享内存并发性。我们可以在这里讨论这个区别,因为从技术上讲,JavaScript 与 web worker 具有并发性,但是它没有共享内存并发性。我可以解释为什么我们需要编译器,但这也是必须的。当你看到所有这些 —— 然后,当然,我们需要好的工具 (我们都生活在 VS 代码中,我们需要 VS 代码中的优秀支持,等等)—— 当你把所有这些加起来,Go 实际上在列表中排名非常靠前。

[19:14] 为什么不是 C#?

Dimitri: 考虑过 C#吗?

Anders: 是的,但是我要说,我认为 Go 绝对是。我要说,它是我们能够使用的最低级别的语言,而且仍然具有自动垃圾收集功能。这是我们能够使用的最原始的语言,而且还有自动 GC 。在 C # 中,如果你愿意的话,它首先是某种字节码;有一些可用的提前编译,但它并不适用于所有平台,而且它没有像 Go 这样经过十年或更长的时间来不断加强。C#一开始并不是这样设计的。此外,我认为 Go 在数据结构布局、内联结构等方面更具表现力。对于我们来说,另外一件事是我们的 JavaScript 代码库是以高度函数化的风格编写的 —— 我们使用很少的类;事实上,核心编译器根本不使用类 —— 这实际上也是 Go 的一个特点。Go 是基于函数和数据结构的,而 C # 是高度面向对象继承的,我们必须切换到一个面向 对象范例才能转移到 C # 。这种转变将涉及更多的摩擦,而不是切换到围棋。归根结底,这是我们阻力最小的道路。

Dimitri: 太好了,我是说,我对此有疑问。我过去在函数式编程中用 Go 语言挣扎了很多,但我很高兴听到你说这些对你来说不是挣扎。这是我的问题之一。

Anders: 当我在这里说到函数式编程时,我指的是那种简单意义上的函数式,我们处理的是函数和数据结构,而不是对象。我说的不是模式匹配高尚的类型和单子。

[23:44] TypeScript-Go 的内存消耗只有一半 (同时还有 10 倍速度的改进)

Anders: 你可以有 bytes, int16, int32, int64 ,uint64 等等。在 JavaScript 中,一切都是浮点数。我的意思是,你想代表真实还是虚假?是的,这对你来说是八位。所以,这很难,这就是为什么我们在现有的编译器中做各种各样的技巧。至少,在 JavaScript 中,我们可以将 31 位打包成浮点数。但是在 Go 中,我们可以使用所有的位,顺便说一句,我们也可以将它们排列成内联结构和数组。它表明,我们的内存消耗大约是旧编译器使用的一半。在这些日子里,内存等于速度:你使用的内存越多,你的速度就越慢,因为你遇到写障碍或读障碍的次数越多(并且你破坏了你的 L 缓存、L0 缓存),然后你必须从真实内存中获取它。我经常开玩笑说,在现代 CPU 中,由于预测,每条指令需要零个周期——除非你碰到内存墙,必须去取,所以需要一千个周期。所以,如果你能压缩你的数据结构,你会跑得更快。

[58:36] 从 JavaScript 到 Go 的过渡实际上相当温和 (比起 Rust)

Anders: 我想说,从 JavaScript 到 Go 的过渡实际上对系统来说非常温和。它不是一种非常复杂的语言,没有太多的仪式,我想说 Rust 更接近于这些复杂的仪式。我的意思是,Rust 更像是一个现代的 C++,而不是一个现代化的 JavaScript ,而 Go 在某些方面实际上是一个现代化、原生的 Python/JavaScript 。

Dimitri: 当我专业编写 Go 大约两年的时候,在一次全员工程会议上,有一些工程师在抱怨。其中一人说这很平庸,他们只是不满足于不能在 Go 中做花哨的事情。我永远不会忘记,这位 CTO 打断了他们并说到:“你必须明白,Go 在设计上是平庸的;它并不想花哨。”

Anders: 它试图成为一种简单的语言——说实话,确实如此。但结果并不平庸。我的意思是,10 倍,这完全不平庸,对吧?所以,你可以用这个东西做伟大的事情。

举报· 1777 次点击
登录 注册 站外分享
16 条回复  
jjx 小成 2025-3-12 10:22:21
Anders 都 65 了吧, 还在探索, 汗颜
jaylee4869 小成 2025-3-12 10:24:25
TS 原本 JIT 就很慢,还用它做 Compiler 自举,不慢才怪
qxdo1234 小成 2025-3-12 10:28:13
这说明什么,前端还是要学 go (不是
CyouYamato 初学 2025-3-12 10:34:26
不懂, 是需要开始学 go 语法了吗? 还是重写底层, 对开发人员无感的?
lexno 初学 2025-3-12 10:37:20
@CyouYamato 重写的是 tsc ,就是将 TypeScript 编译为 JavaScript 的那玩意,对于前端开发应该无感
815979670 小成 2025-3-12 10:49:26
套用前几年比较流行的一句话 :任何可以使用 JavaScript 来编写的应用,并最终也会由 JavaScript 编写。 然后再用 Go 改写 https://i.imgur.com/Ug1iMq4.png
ZGame 初学 2025-3-12 10:50:52
以后是不是不能黑前端效率比 java 慢了
MEIerer 初学 2025-3-12 11:03:13
Js 背靠 rust c++ go 就是不能靠自己哈哈哈
MakHoCheung 小成 2025-3-12 11:08:36
??? TS 编译器改用 Go 实现变成用 Go 重写 TypeScript
12下一页
返回顶部