← 返回博客

Zed Weekly: #29

2023年12月15日


随着年底临近,我们都期待着使用 GPUI 2 体验 Zed 全新的坚实基础带来的好处。 看到所有功能在每晚构建中重新上线并开始将新版本的 Zed 用作一个团队是一件有趣的事情。 这是来自前线的一些更新...

Nathan 和 Antonio

GPUI 2 在开发者效率方面有了巨大的提高,但性能必须出色。 随着越来越多的 Zed 在新框架之上重新上线,本周我们真正专注于理解和提高 GPUI 的性能。

对于基准测试,我们使用一个简单的测试,我们按住绑定以 60hz 的按键重复率切换选项卡。

以 60Hz 切换选项卡

这是一个直方图,显示了本周工作的结果。 红色包括一种改进的分配方法,如下所述。 两个不同的集群可以用两个选项卡之间的不同内容来解释。 我们认为还有一些改进的空间,但我们正在接近。

Histogram of frame times
帧时间直方图

一个众所周知的问题是,渲染帧会执行大量分配。 元素树中的每个元素都需要是一个 trait 对象,因为我们希望系统是开放式和可组合的。 例如,必须允许 Div 元素包含任何类型的子元素。

在 GPUI 的早期,我尝试使用 bumpalo 来“bump 分配”所有元素。 通过 bump 分配,每个新分配的值都附加到内存中先前分配的值之后。 因为我们总是分配在末尾,所以不可能释放单个元素并重用该内存,但它也更简单更快。 这非常适合帧渲染,因为一旦渲染了新帧,我们就会删除用于渲染上一帧的所有对象并回收内存。

bumpalo 的问题在于,每个分配的值都带有一个生命周期,该生命周期将其绑定到分配它的 arena,并且这些生命周期给 API 增加了许多复杂性,因此在 GPUI 1 中,我们决定承担 malloc 的成本,并且简单地 box 我们的 trait 对象。

使用 GPUI 2,我们正在分配更多的闭包,并且我们还承担了通过 taffy 执行布局的成本,这比我们旧的方法更昂贵,但同时也更灵活和强大。 为了给自己争取更多的空间,我们最终实现了我们自己的简单 bump 分配 arena,我们在帧渲染期间通过线程局部变量访问它。 我们没有使用生命周期,而是动态地强制执行内存安全,在每次清除 arena 时使我们的引用无效。

我们所做的另一个改变是避免将对象从堆移动到栈。 这是由于我为 Element::paint 移动 self 所做的设计决定造成的。 当时,这似乎是一个好主意,有助于匹配每个元素仅使用一次的语义。 然而,在语义上起作用的东西,在实践中却很慢,因为移动 self 来绘制元素会导致对象从堆复制到栈,没有充分的理由。 将 paint 更改为采用对 self 的可变引用可以加快速度,但人体工程学成本略有增加。

我们还有一些想法将在下周进行探索。 我们的目标是让我们的最高复杂度的全窗口重绘在 M1 上花费 4 毫秒或更短的时间。 然后我们打算使用缓存来避免对未更改的视图执行布局和绘制,这应该为编辑提供更多的空间。 Antonio 或我将在下周再次报告我们在这个目标上的进展。

Marshall

此更新来自 Zed2 的现场直播(好吧,就像书面文本一样现场)!

我本周的大部分时间都花在了打磨 Zed2 的各个部分上。 其中大部分是调整 UI 样式,但在此过程中我可以解决一些错误。

在本周的后半部分,我重新审视了我们的老朋友 theme_importer,以提高导入的 VS Code 主题的质量。 这是一项有点棘手的任务,因为每个 VS Code 主题都以其应用样式的方式独一无二。 最初感觉就像一场打地鼠游戏,导入器中的一项更改修复了一个主题,但不可避免地导致另一个主题出现中断。

花了一些时间后,我对结果非常满意,到目前为止,我们已经能够导入一些不同的主题系列,并使它们在 Zed2 中看起来很棒。

我期待着在即将到来的一周里在 Zed2 中测试这些新主题,因为我开始在日常编码中认真使用它。

Joseph

本周,我有机会学习和使用新的 UI 框架来移植我们的反馈 crate。 我真的很高兴它让我能够真正将一些代码放入 Zed 并快速迭代 UI 更改。 我们正在从编辑器选项卡切换到带有嵌入式编辑器的模态窗口。 移植体验有点挑战性,但仍然很有趣。 我很高兴看到这个新库如何增强对 Zed 贡献感兴趣的人的社区。

Julia

在过去的几天里,我一直在追查与 Antonio 和我对焦点处理程序的调用时间所做的更改相关的测试失败。 我们在编辑器拆分方面存在时序问题,当我们运行焦点更改的焦点处理程序时,新创建的编辑器窗格尚未呈现。 因此,工作区永远不知道哪个窗格收到了新的焦点,并且命令调色板操作将继续影响原始编辑器窗格。

我们将焦点处理程序更改为在每次帧绘制时调用,在元素树被渲染之后,这样我们就可以获得有关焦点树结构的最新的信息。 不幸的是,一些测试假设焦点处理程序会立即被调用,这需要修复,并且更多的测试假设可以在不实际渲染的情况下聚焦某些东西。 调试每一个都需要时间和大量的调试打印来捕获焦点循环,但最终分支变成了绿色:)

Nate

待办事项清单一直在增长,但不知何故,我们正接近能够每天使用 Zed2 来构建 Zed2 的阶段。

The state of Zed2 today!
Zed2 现在的状态!

(我的 UI 比例非常小,所以如果看起来很小,请不要担心。)

对于这个项目,能够朝着终点线迈进,真是令人兴奋 – 虽然新的应用程序感觉会很棒,但解锁快速迭代应用程序的能力才是真正的胜利!

我们也已经能够发布一些我们和其他人一直想要的自定义设置。这是一个小视频,展示了其中的一些

UI 变得高度可配置。 这是一个可以更改的许多设置的示例。

我的简短更新,但我会继续埋头苦干,继续前进!

Nathan 再次

感谢您的耐心等待,因为我们一直在取得表面上不太明显的进展。这项工作实际上是为您创建一份优美的代码库,以便在明年我们开源代码库时您可以使用。放慢我们可见的进展一直很困难,但随着大修接近完成,我越来越相信这项投资将在未来几个月和几年内获得回报。感谢您的阅读!


注意:Zed2 并不意味着新的版本号,它只是我们内部使用的一个别名,用于表示使用新 GPUI 框架的 Zed 版本。