在与 Nathan、Max 和 Antonio(Zed 的三位联合创始人)进行上次对话后,我仍然有很多问题要问:你们为什么做出那些技术选择?Rust 对 Zed 有多重要?你们是否有意识地想要像现在这样拥有整个技术栈?你们如何决定哪些要精雕细琢、一劳永逸地构建,哪些要更快地发布?
幸运的是,他们再次与我坐下来,再次回答了我的问题。
以下是我们一个小时对话的编辑稿。我尽量保留了原意,同时删除了“嗯”、“像”、“你知道的”以及深度对话中常见的停顿和纠正。
(你可以在我们的 YouTube 频道上观看完整对话。)
Thorsten:你们三位已经合作了多久了?有10年了吗?
Nathan:Ungefähr。[德语,意为:“差不多。”]
Max:是啊,差不多。
Antonio:我觉得10年差不多。2014年,是的。
Thorsten:Atom——那是10年前的事了。你们一起开发了 Atom,然后说“我们要构建 Zed”。很明显,你们对要构建什么有一个愿景。而且你们也做了一些非常独特的技术选择。你们使用 Rust,它是 GPU 加速的,还有 CRDT。我好奇的是:这些技术选择与 Zed 的愿景有多大关系?技术扮演了多大的角色?
Nathan:嗯,从我的角度来看,Zed 的愿景只是 Atom 最初愿景的一个更精炼、更充实版本,只是因为我们当时做出的技术选择以及我们开始开发 Atom 时我认为我们所有人的技术成熟度不足而未能实现。
但我一直以来的目标是,一个我喜欢使用的、感觉像文本编辑器一样轻巧、极简的编辑器,但在需要时又具有 IDE 的强大功能,没有所有缓慢的体验和用户界面的沉重感,但仍然强大。这是我早期就想要的。而且它必须可扩展。
你知道,我记得使用 Emacs 时觉得它可以扩展真是太酷了,但你基本上是在字符级别操作。所以这也是最初愿景的一部分,现在 Max 用 Tree-sitter 实现了这一点。你知道,基本上就是可脚本化。我们还没有可脚本化,但我们会实现的。但当我们实现时,我们将能够访问比仅仅循环字符或我在 Emacs 中所做的任何事情更丰富的文本表示。我的意思是,他们现在可能也有了,对吧?因为 Max 写了 Tree-sitter。
Max:他们有,我听说。
Nathan:那太酷了。但总之,这一切都是愿景的一部分。只是在 Atom 上没有实现。我的意思是,当 Chris 雇我开发 Atom 时,我差点就没有加入(意思:加入 GitHub 开发 Atom),因为我害怕使用网络技术,怕它无法达到目标。
但说实话,我不知道当时我所掌握的任何东西是否能让我们做得更好,因为 Rust 当时还不存在。所以它会是 C、C++。我不知道,在我们创建 Atom 的时候,要用原生技术做点什么会非常困难。而且我认为我当时在文本编辑至关重要的基本算法等方面还没有掌握好。C++ 会大大减慢我在那里的学习速度。所以我认为它就是这样发生的,必须如此。
我们用 Atom 达到了一定程度。2017 年我们发布了 Teletype,感觉就像,好吧,不再是我们自己的无知阻碍了我们,而是在这一点上,真的是平台阻碍了我们。当时就是这种感觉。仅仅是 JavaScript 中数组的事实……你以为你有一个对象数组,但你实际上是一个指向对象的指针数组。所以每次你遍历它,你都在追逐它。你无法控制内存。有垃圾回收器暂停发生,你无法控制。你只需查看该死的配置。
Thorsten:当你们开发 Atom 时,有没有一个特定的时刻,你们说“哦,我希望我们能用 X 来构建它”?还是说是一点点问题累积起来的?Antonio 现在正在点头。
Antonio:说到开发这个东西十年了:我记得我在 Atom 中的第一个项目之一——我不知道你是否还记得,Nathan——是加快行布局。基本上,我们发现行布局非常慢。我记得尝试在 iframe 中渲染行。我记得使用 Canvas、测量文本以及所有这些 API,它们……我不知道,Canvas API 和浏览器 API 不完全一样,所以你无法正确测量文本。iframe 的东西还有一些其他奇怪的问题。
我在 Atom 的经验总是感觉像是在竭尽全力去实现一些原则上应该很简单的事情。布局一些行,然后读取光标在两个字符之间这个位置的坐标。这似乎是根本上可行的,但总是感觉工具不趁手。它们离我们想做的事情很远。
Nathan:那真是一场噩梦。我的意思是,讽刺的是,我们创建 Electron 是为了创建 Atom,但我无法想象还有比代码编辑器更糟糕的 Electron 应用了,我不知道。对于更简单的东西来说,它可能还行,内存占用很糟糕,但还行。但对于代码编辑器,我认为你就是没有那种控制水平,无法以至少是直接的方式来做这些事情。它总是有些……花里胡哨。
所以,在 2017 年某个时候,我记得坐在那里,在我的日记本上用 Atom 写东西——那天晚上我想:我们必须重新开始。我们必须重新开始,这行不通,我们永远无法让它达到我们想要的目标。VS Code 在这方面做得很好,它已经尽可能地做到了最好。我相信技术会有渐进式的改进,但我就是想要更多。
所以在那时,问题是:我们该怎么做?我一直在关注 Rust,看过 Raph Levien 关于 Rust 的一些文章。当时这似乎是克服这些障碍的唯一可行途径。它最初的想法是:如果我们只用 Rust 编写核心部分,而将 Electron 作为表示层呢?
所以我们是逐步做出这些技术决定的。甚至在构建 UI 框架,放弃 Electron 之后,我们还在使用 Pathfinder,这是一个非常酷的项目,基本上可以任意呈现 SVG,但它太慢了。所以我当时想:好吧,如果我们自己写着色器呢?然后去学习了有符号距离场。
这有点好笑。是我不想解决一些更根本的问题,但由于没有其他选择,我被迫去做了。
我不该说那只是我,那不只是我。但这只是我的看法……
Thorsten:听起来你们的目标始终是尽可能快、尽可能轻量。你们尝试过实现,但现有技术无法做到。后来 Rust 出现了。你们并不是一开始就说“我们需要一个 GPU 加速的编辑器”,而是说你们想要最快的编辑器,然后 GPU 加速是实现这一目标的一种方式。对吗?
Nathan:是的,我们是这么想的:电脑里有这个硬件,与其争论 DOM 中某个时刻有哪些 DOM 节点,或者所有这些废话,我们不如直接问:这个像素应该是什么颜色?太好了。好吧,如果我们能编程这个硬件来并行决定屏幕上每个像素应该是什么颜色,或者尽可能并行——如果我们想快的话,我们应该使用它。
但你知道,我们是有点不情愿地走到这一步的,因为我根本不知道怎么做这些。
Thorsten:现在,这是一个有点带倾向性的问题,但我过去三年一直在用 Rust 编程,我对它的感情很复杂。但两周前,Hacker News 上有人说 Zed 中的“查找所有匹配项”需要一秒钟,而在 Sublime Text 中却非常快,接近 200 毫秒。于是 Antonio 和我一起研究了这个问题,他编写了代码来优化在这种情况下搜索缓冲区中所有出现项的性能。但优化后的代码并不是“优化”过的代码:它没有使用任何黑科技,没有 SIMD 或类似的东西。它是高级代码,优化之处在于它的假设不同:它不是循环地逐个执行,而是假设要找到所有结果。我们制作了一个发布版本,结果从 1 秒下降到 4 毫秒。
Antonio:哈哈哈
Thorsten:我坐在那里,看着 4 毫秒,然后……嗯,我想:这之后将是一个愉快的午餐时间。但是 4 毫秒?用那样的高级代码,只是调用了其他内部 API?哇。所以我想问的是:Rust 有这些零成本抽象——所以你可以使用高层次的抽象来构建文本编辑器,但它仍然能给你带来这种性能。你认为这是 Rust 的一个特殊之处,还是说如果你是一个更好的 C++ 或 C 程序员,你可以在其他语言中做到这一点?
Antonio:你可能可以用 C 和 C++ 来做。我不知道。我的意思是,tree-sitter 是用 C 写的,对吧,Max?所以用 C 编写一个复杂的软件库是可能的。尽管我不得不说,每次我看到 tree-sitter 中的 C 代码时,我都会尖叫,因为它对我来说太多了。我不知道。
就我个人而言,是的,Rust 处于一个非常好的位置。如果不是编译时间那么慢的话——这是我非常不喜欢这种语言的一点,但也许是我们的项目太大了,我不知道。
但是是的,你可以在这些抽象之上进行构建并依赖它们,这真是太酷了。我的意思是,我不知道零成本——我想每个抽象都有成本。
但这个项目总的来说……在 Atom 上,我们总是感觉不知道该从哪里寻找性能。而在 Zed 上,更多的是:我们可以这样做,也可以那样做,我们可以改进这个。就在上周,Nathan 和我还在讨论如何改进 SumTree 的减法操作,以便更快地进行批量插入。
Nathan:然后你实现了,对吧?
Antonio:是的。但还没发布。
Nathan:太棒了。
Max:我要说我们在 Atom 上确实做了很多 C++——我们做了很多。我们尝试了。而且它奏效了,但有一个非常重要的区别——显然——JavaScript 应用程序代码和 C++ 库代码之间的界限在哪里。人们会谈论性能,说“只需在后台线程上执行此操作,不要在主线程上执行”,我们会说“好的,我们可以这样做”,但这意味着涉及到的整个子系统需要放入 C++ 中才能共享内存。然后围绕它构建 JavaScript API,并弄清楚它将如何仍然看起来像地道的 JavaScript 代码,并保留它用 JavaScript 编写时所具有的所有这些属性。
只有这样我们才能真正将这个任务转移到后台线程。
编写 JavaScript 代码(可脚本化、可插拔、可重写)与具有共享内存和多线程核心能力的 C++ 之间存在巨大差异。
Nathan:Rust 被设计为多线程。我记得当我尝试学习 Rust 时,我想要实现这个 splay 树,因为 splay 树是我们在 Atom 中经常使用的一种结构。好吧,有一段时间——它至少有它的时代。我的意思是,它实际上非常适合我们的需求,但它有父指针,它是一个非常可变的结构。
我尝试在 Rust 中构建它,但语言与我作对。我当时想:这种语言能构建出真实的东西吗?我当时确实有严重的怀疑。
所以我放弃了一段时间,然后我又尝试了。这次我构建了一个写时复制 B 树。当我那样构建它时,它使用了 Arc,这意味着它本质上是多线程友好的。
当我遵循语言的指示和借用检查器,并按照 Rust 想要的方式去做时,我感觉:哦,太酷了。
现在我们有了表示 绳索 的方法——绳索是 Zed 中基本文本存储结构——我们可以生成一个后台线程,它的时间复杂度是 O(1),它只是通过增加一个 Arc 来将它带到后台线程并查看快照等等。
这不仅仅是关于原生。我还认为 Rust 带来了创新。这种语言被设计成可以在多个线程上以低级别使用。
坦率地说,我想我在 C++ 方面有点像个脚本小子,做不好。它总是让我烦恼:那些该死的文件,跳来跳去,所有这些神秘的规则。一个 C++ 大师能做到我们在 Rust 中所做的事情吗?可能吧,但我不会成为那样的人。
Thorsten:Antonio,你刚才提到用 JavaScript 时,你不知道从哪里寻找性能。Max,你说当你使用 C++ 或 JavaScript 时,你想让某些东西异步执行时会感觉到这些边界。现在我们听说了 Rust——你突然可以在后台线程上异步执行任务,限制更少,可以自由移动。
这让我想起了 Zed 代码库中实际可以看到的东西:你们拥有整个技术栈。从 Tree-sitter 进行解析到 GPUI,这个 GPU 加速的 UI 框架——代码库中没有很多第三方依赖。有一些库,但没有大的构建块。
这对你有多重要?我们拥有从上到下完整的技术栈,我们从上到下都理解它。这是有意识的选择,还是因为 Max 构建了 Tree-setter,然后你们做了这个,现在看看我们,我们重建了整个东西,所以这一切都是偶然发生的?
Max:我不知道。我觉得它有取舍,但到目前为止,能够……决定我们想要事情如何运作,这感觉很好。就像现在:我们想要使用 WASM 的语言扩展。Tree-sitter 没有这个,但我们把它添加进去了。
像这样的事情有很多。我们不想受制于某个 UI 框架,它可能无法完全按照我们想要的方式渲染文本,因为我们是一个文本编辑器,这很重要。但我们现在可以去改变它。
感觉没有什么东西是完全不能触及的。
Nathan:我要说一件事:这很大程度上受到了我职业生涯早期 jQuery 经验的影响。jQuery 当时很流行,我学了 jQuery。我记得 Yehuda 来到 Pivotal 介绍了 jQuery,我觉得这太酷了。我被它震撼了。所以早期,所有的 Atom 代码,信不信由你,都是 jQuery。
但有趣的是,学了 jQuery 之后,因为每个人都告诉我,“哦,你使用 jQuery 的原因是因为它抽象了浏览器 API 的所有差异”,等等。我从未真正质疑过这一点。但后来我记得有一天,我只是坐下来阅读了该死的 DOM API。然后我想:你知道吗,这实际上很好。也许缺少一些功能或什么的——我不想贬低 jQuery,我认为它有它的作用——但我从中得到的结论是,如果我没有一个几乎 100% 满足我需求的抽象,那么我可能不想使用那个抽象,而是回到更低的层次,完全理解更低的层次,并做我需要做的事情。
GPUI 的情况就是这样。2019 年我们开始开发 GPUI 时,有一些 UI 框架正在开发中,但没有一个能满足我们知道我们需要做的事情。而且我也不理解它们。
但我知道我可以很容易地理解我们将要依赖的基本原语——语言、图形框架。我知道我们可以学习这些东西,而且我知道我们写了很多代码。如果我能构建一个我可以理解和学习的系统,那么我知道如果它在底层系统上根本上可行,我就可以做我们需要做的事情。所以,对于 GPUI 来说,这实际上是一种生存策略:我需要理解它,而理解它的最好方法就是构建它。
Thorsten:那有什么缺点呢?Max,你说有取舍。
Nathan:永远需要时间。太慢了。
Antonio & Max:[笑]
Antonio:新人上手也挺麻烦的。你用的不是大家熟知的 X 框架,你得从头开始教这个代码库——你知道,30万行代码。这是一个缺点。
但酷的是,虽然这是一个缺点,但与此同时,有人写了这些代码,并且可以向新人解释。
它可能会慢一些,但你再次获得了控制权。
Nathan:我认为它会积累。优势会积累,劣势会贬值。有人刚刚在 GPUI 上构建了另一个应用程序,所以我们现在有了另一个利益相关者。拥有它的成本,我们将随着时间的推移逐渐摊销,而拥有它的成本和好处将开始显现。
Thorsten:有时人们会说:我只构建一次,然后就再也不用碰它了。与之相反的可能是:你无法预测未来,越烂越好,等等。
而你刚才说的,自己构建所有东西会比较慢,这其中有一种“一次构建,并为我们的用例做得正确”的意味:只为我们想要做的事情提供完美的抽象。与此同时,你们都有这种紧迫感。我的意思是,我四周前才加入,我觉得我们进展很快,而且还有很多事情要做。
你如何平衡这一点?你如何拥有如此宏伟的构建愿景,并将其与“我要编写着色器,我要完善如何渲染阴影或其他东西”这句话进行平衡?
Nathan:构建你需要的东西,只构建你需要的东西,不多不少,并在合理范围内尽可能做好。当它被证明不是你真正需要的东西时,在你学习之后,愿意重新审视它。但我想如果你每一步都带着意图和细心,并且你没有浪费时间去猜测你可能需要什么,那么……对我来说,这总是奏效的。尽管有时需要一点时间。
Antonio:我还要补充一点:这是一个渐变过程。不是所有东西都需要完美构建。至少我对我们编写的大部分代码是这样认为的。如果我们在 GPUI 中编写代码,那么整个应用程序都依赖于 GPUI,那最好是完美的。或者是求和树。它是代码库中随处可见的数据结构。这个我们真的想搞定,因为它必须很快。
它必须完美运行,这样我们才能在其之上构建,对吗?这一点也体现在我们对这些东西的测试中。SumTree 进行了随机测试,因为我们想确保所有这些边缘情况都能完美运行。
现在,当你接近边缘时——你提到的那个性能改进,Thorsten,我们没有花三个小时去精雕细琢,对吧?它更像是:只要能完成任务就行,它基本上就在边缘。我的意思是,我们应该对代码感到满意,我们应该始终努力写出最好的代码,但我们不需要精雕细琢。
这是一个渐变。越是核心的东西,越值得深思熟虑和高质量。
Nathan:我最喜欢写的代码是那些我通过努力赢得权利去写的代码。哇,好多同音异义词。
用 GPUI 编程让我非常开心,以至于我几乎感到内疚。但我赢得了编写这段代码的权利,因为我编写了第一个版本,我与它共存,我推动了它,我在需要时做出了妥协,以使事情变得正确。
但现在是我们可以做得更好的时候了。而且这样做是有意义的。我对此有了解。我想很多时候人们谈论重写——如果你正在重写别人写的东西,那就要加倍怀疑自己。
但如果你写了它,并且你已经习惯了它,并且你付出了努力……还有一点要说:不要让完美主义阻碍了学习。
Thorsten:如果我要带你们三位去……我不知道有什么你们建不出来的东西,但假设你们必须建造,我不知道什么——一架飞机的 PID 控制器。飞机软件,就这样吧。类似的东西。
Nathan:核反应堆控制子系统。
Thorsten:你不知道这个领域,你也不知道要怎么构建,你也不知道你需要哪些部分。在这种情况下,你会说需要不同的方法吗?不像在编辑器中,你对你想要什么有强烈的愿景,你之前已经构建过一些,所以现在你知道哪些部分很重要。你事先就知道,GPUI 会很重要。所以我们花时间去完善它,正如 Antonio 所说。
Max:我的意思是,我不知道核反应堆是不是一个好例子,但我确实觉得,如果这是我们的第一个代码编辑器……我们确实实践了“越烂越好”。它并非故意烂,但我们确实尝试过一次更快速、更粗糙的方法,然后识别出那些在“越烂越好”的形式下难以构建的真正痛点。
但我确实认为,如果出于某种原因,Antonio、我和 Nathan 必须构建一个……
Nathan:也许选一个不那么关键的任务?
Max:……一个 Shopify 克隆之类的东西。我们可能就会有不同的心态。我们不知道哪些部分需要高度打磨。
Nathan:但是如果我真的要构建一个核反应堆控制系统,我就会使用拜占庭容错共识算法,让三个团队相互对抗,互相破坏对方的安全性,然后让他们在所有事情上达成共识。但我不知道怎么做。
Antonio:还有一个例子,虽然不如核反应堆那么关键,但我们不知道数据结构,而且我们花时间去学习了。Atom 和 Zed 中用于缓冲区的结构并不是一开始就是 CRDT。有一段时间的研究期,Nathan 和我阅读了……我忘了多少篇论文了。很多。我们现在使用的 CRDT 方法——我们仍然重写了两次或三次——但方法或多或少是一样的。
所以我觉得其中一部分来自于经验。我感觉你往往会培养出一种感觉,知道哪些事情需要花时间,哪些事情更不重要。
话虽如此,我们确实重写了 CRDT 两三次,但研究部分很重要。我不知道。
Nathan:有趣的是,发布版 Atom 中的缓冲区是一个行数组,一个 JavaScript 字符串数组。而在 Zed 中,它是一个多线程友好、可快照的写时复制 B 树,可以索引所有你能想象到的东西。或者所有我们需要的。所以我们做得越烂越好。
但如果重新开始,还会是一个行数组吗?可能不会,因为看看它的时间限制。再多思考一下,但那——再次——我是通过“越烂越好”的方式学到的,然后它在最终很重要的边缘情况下变得非常慢或有问题。
Thorsten:那么 Zed 最精雕细琢的部分是什么?
Nathan:我觉得 GPUI 相当精雕细琢,因为我们刚刚重写了整个该死的东西。
Antonio:好问题。
Max:我认为 editor crate 中的内容,那里有不同转换的堆栈,它们将缓冲区的原始文本转换为你在屏幕上看到的行,展开制表符并进行软换行,插入块装饰并处理折叠等等。所有这些层都有统一的测试策略,即通过属性测试进行随机测试。所以我觉得它们非常精雕细琢。
多缓冲区也是,我们将不同缓冲区的不同片段编织在一起。
Nathan:我会称它们为……我只是想为代码库的那个部分提出另一种物质。我会说它是用血镀金和涂层的。
Antonio:哈!血镀金。
Thorsten:你是说编辑器和多缓冲区吗?
Antonio:是的。
Nathan:是的。那是随机测试,我们确实在 2021 年花费了整整一天,连续多天,只是调试这些随机测试中的故障,这些故障会发现这种华丽——我的意思是,我不会说它华丽,但它很复杂——将不同层次的转换堆叠在一起才能在屏幕上呈现东西的奇怪边缘情况。所以这只是苦力活,对吧?找出边缘情况,然后通过减少日志来找出它们为什么会发生,而我们很长一段时间都是手动完成的。
Thorsten:当这些 bug 出现时,你们感觉如何?有没有过恐慌的时刻,当属性测试把 bug 甩在我们脸上,你觉得“也许这一切都行不通”?还是说“好吧,这只是另一件需要打磨的事情,如果不行,我们就重写”?
Antonio:从不恐慌,这是随机测试的规则,从不恐慌。我非常相信我们作为工程师的能力,我确实如此,也许我们必须重写整个东西,随机测试正在告诉我们这一点,但没关系,我们只是学到了一些东西,回到绘图板重新做。
Nathan:可怕的是:这要花多长时间?我想 Lee,我们的种子投资者,有时也问过我们这个问题。但他坚持了下来,并保持了耐心,因为这确实花了一段时间。
但那部分是用 Rust 写的。如果我们搞砸了,程序就会崩溃。再见,砰。它不仅仅是像一个堆栈跟踪被扔在编辑器的角落里,不,它就结束了。
所以我们知道要让那些层级正确有多难。我们也知道别无选择,只能让它们正确。但是的,我记得,Antonio,你还记得在软换行上工作,以及我们遇到的那个问题,我们意识到我们需要的基本原语是能够表示一个补丁,然后能够将这些补丁组合在一起——那是我有点出汗的时刻,想着“我们到底能不能搞定这个?”然后 Antonio 搞定了。
Antonio:是的。但驱动这一切的——你知道,就精雕细琢而言——仍然是求和树。即使如此,如果我们要重写它,仍然有一些想法可以使其更好。
Nathan:前几天晚上我们还在聊那会多棒。Antonio,你应用了一些我们谈论过的想法:能够以更友好的流式方式构建所有这些层。你还做了一个优化,下周将会在预览版中上线。
Antonio:是的,我还需要为它开一个 PR……
Nathan:为了实现更多的流式输入,这样人们在打开大文件时就不会得到零反馈,而是开始更高效地加载内容——这是否需要重写?也许吧。也许不是。我不知道。
Thorsten:这个重写或重做的主意经常出现,这很有趣。我们上次也谈到了这个问题。持续学习。它不是:学习,然后修补。它更像是:我们学到了一些东西,所以现在让我们带着这些知识重新做一遍,而不是仅仅打个补丁。它出现了好几次,你可以在产品中看到。
Antonio,当我们聊天时,你总是说:“以前我们是这样做的,现在我们是那样做的。”就在昨天,我们基本上重写了处理 macOS IME 系统的部分,因为 Antonio 说:“我们不能就这样放着,我们不想让另一个人掉进这个兔子洞,我们来搭一座桥吧。”
Nathan:不错。很高兴听到这个。我听说过。
Thorsten:我不知道是否有意义,但我的最后一个问题是……对于许多软件,比如 SaaS 企业版,或者 Shopify 克隆,我认为大多数用户并不关心使用的是什么技术,只要它能为他们服务就好。我想知道:你认为这对于开发工具或编辑器来说有所不同吗?所使用的技术会更明显地体现出来,还是用户更关心它呢?
Max:我确实认为这会影响我们能获得的贡献类型。我们的许多用户,其中很多人都愿意为代码库贡献一些东西来满足自己的需求。
我认为 Zed 易于贡献很重要。如果我们将它全部用 C++ 编写,我认为会有很多人想要改变 Zed 的某些东西,但却不愿意自己动手进行改变。
然而,自从几周前开源以来,我们获得的贡献很多。我认为人们喜欢它是用 Rust 编写的。它平易近人。人们可以轻松地构建项目。他们不必学习如何使用 CMake 或 Gyp 来构建项目。他们只需使用 cargo。
但编译器这种严格性也让我们这些贡献的接收方,能够经常自信地合并。我认为这真的很有帮助。
Nathan:Rust 绝对是一个美丽的工具。它不完美,但我爱它。但它对人们重要吗?我的意思是,我认为人们最终想要一个快速的编辑器。我们可以用,是什么来着,brainfuck 编写它?他们不会在乎。但贡献的角度是非常有效的。
Antonio:但我还是想谈谈性能问题,我只是觉得我们被迫以某种方式做事,因为性能。为什么我们有这个 GPU 加速的 UI 框架?因为性能需要达到一定的水平。我们希望我们的帧率低于三毫秒。我们可以在 CPU 上光栅化所有东西,我们也可以使用那样做的东西,但不,我们没有。
在某种程度上,我们正在将自己定位为一个高性能编辑器,因为我们想要一个高性能编辑器。我想要一个高性能编辑器。所以,选择几乎是……我们几乎别无选择。
Nathan:但是现在有 Zig 了,我对 Zig 了解不多,老实说,我还没有时间去学习它,但我尊敬的人们对它很兴奋。它似乎在输出方面与 Rust 有一些相同的目标。我不清楚它在安全性方面牺牲了什么,或者他们如何处理这些事情。可能有一些务实的变通方法,不如 Rust 严格,但实际上可行,等等。
所以我对此很感兴趣。我很感兴趣,但对于像单语主义这样的东西,也有很多话要说,如果这样说有意义的话。服务器是 Rust,前端是 Rust,但如果我能以十分之一的编译时间获得 Rust 99% 的好处,或者类似的东西……
Thorsten:嗯,我可以告诉你关于 Zig 的事情,Discord 上有人说他们正在用 Zig 写一个编辑器,但是用 Zig 编写文本编辑器的完美名字已经被占用了:Zed。