使用 bisect 解决扩展问题
2021 年 2 月 16 日,作者 Johannes Rieken,@johannesrieken
“就像 git-bisect,但用于 VS Code 扩展。”
Visual Studio Code 的真正强大之处在于其扩展:主题扩展添加颜色和图标,语言扩展启用智能代码完成 (IntelliSense) 和导航,调试器扩展使您能够运行代码并轻松查找错误。有些扩展可以播放音乐,有些可以显示股票行情,还有一些扩展可以实现跨地点和时区的协作工作。VS Code 市场 托管着超过 28,000 个扩展,用户安装 50 个或更多扩展并不罕见。由于有如此多的扩展,bug 是不可避免的。我们不想否认,而是希望使故障排除变得容易。
“坏”扩展
我们喜欢扩展,并且真的不认为有任何“坏”扩展。然而,像所有软件一样,扩展也存在 bug 和功能缺陷。因此,为了方便阅读和人为的戏剧性,让我们使用术语“坏扩展”,它指的是可能崩溃或只是显示不良行为的扩展。幸运的是,我们在设计 VS Code 时考虑到了“坏”扩展,因此将它们在单独的进程中运行。这种隔离保证了 VS Code 持续运行,光标始终闪烁,并且您可以随时保存您的工作。
为了好玩,并使演示扩展 bisect 更加容易,我们创建并发布了 Extension Bisect Demo 扩展。安装后,每当您输入单词“bisect”时,它都会烦人地重置您的光标。您可以使用此扩展来跟随这篇博客文章的步骤。
艰难地找到“坏”扩展
今天,找到“坏”扩展可能很容易也可能很难。打开扩展视图(⇧⌘X (Windows, Linux Ctrl+Shift+X)),禁用扩展,重新加载窗口(开发者:重新加载窗口),并检查问题是否仍然存在。如果问题消失,则该扩展是“坏”扩展,您就完成了。否则,重新启用该扩展并对下一个扩展重复此过程。
如果您幸运,第一个扩展是“坏”扩展;如果您不幸,则是最后一个扩展。使用计算机科学语言,这意味着对于 N
个扩展,您最坏情况下需要重复此过程 O(N)
(阶数为 N),平均情况下为 O(N/2)
。由于此算法由人(您)操作,即使 N
的值很小,也很费力。这就是 扩展 bisect 实用程序派上用场的地方。它在最坏情况和平均情况下都更好,因为它每次禁用一半的扩展。
欢迎使用扩展 bisect
VS Code 中的扩展 bisect 实用程序灵感来自 git bisect 命令。对于熟悉 Git 的人来说,此命令有助于找出仓库中哪个提交引入了问题。
让我们使用一个示例:我安装了 24 个扩展,第 8 个扩展是“坏”扩展。我们知道迭代方法需要 8 步。那么 bisect 呢?
下面的视频演示了如何通过 帮助:启动扩展 Bisect 命令启动扩展 bisect,然后选择 现在正常 或 这很糟糕,直到找到“坏”扩展。找到后,您可以选择为该扩展报告问题。
以下是逐步找到“坏”扩展的方法
- Bisect 将 24 个扩展分成两半,每半 12 个扩展,并禁用后一半的所有 12 个扩展。
- 在本示例中,第 8 个扩展是“坏”扩展,因此它在前一半,未被禁用。事情仍然没有像我们期望的那样工作。由于仍然存在问题,扩展 bisect 重复此过程,将前 12 个扩展分成两部分:6 个启用,6 个禁用。所有其他扩展也重新启用。
- 第 8 个扩展现在被禁用。现在情况良好。这意味着 bisect 可以继续对后一半(扩展 6-11)进行操作,并将它们分成 3 个启用和 3 个禁用的扩展。
- 现在,第 8 个扩展被重新启用,问题再次出现。这意味着 bisect 继续对前半部分进行操作。它将它们分成 1 个启用和 2 个禁用的扩展。
- 第 8 个扩展现在被禁用,情况再次良好,并且 bisect 继续对后一半进行操作,将其分成 1 个启用和 1 个禁用的扩展。
- 第 8 个扩展是唯一禁用的扩展,并且问题已消失。这意味着我们找到了“坏”扩展,并且我们完成了。
更快地进行故障排除
我们看到,在每个步骤中,bisect 都将搜索空间减少一半。现在的步骤以对数时间运行,导致平均和最坏情况下的性能为 O(log N)
。这非常好,因为它具有良好的可扩展性。对于 24 个扩展,您需要 4 到 5 步来找到“坏”扩展,对于 38 个扩展,只需要多 1 步。然而,最好情况更糟,因为使用迭代方法,您可能会很幸运地在第一轮中找到“坏”扩展。
请记住,扩展 bisect 依赖于您提供正确的反馈。您很容易通过始终回答 现在正常 (责怪最后一个扩展)或 这很糟糕 (找不到扩展)来愚弄它和你自己。
另一个有用的见解是,扩展 bisect 从考虑已启用扩展的完整列表开始。这意味着您可以通过在启动 bisect 之前禁用已知的“良好”扩展,并在之后重新启用它,从而将其从 bisect 中排除。但是,只有当您确定该扩展不是“坏”扩展时才这样做。
最后,您可能会注意到 bisect 多执行了一个步骤 (log2(N) + 1
)。这是因为它的第一轮从禁用所有扩展开始。执行第一步是因为您可能看到的问题是由 VS Code 本身引起的,而不是由扩展引起的,我们不想不必要地让您陷入兔子洞。
就是这样。我们希望您永远不需要使用扩展 bisect。但是,如果您确实遇到可能与扩展相关的问题,那么我们希望我们可以使故障排除更容易、更快、更愉快。
编码愉快,
Johannes Rieken,VS Code 首席软件工程师 @johannesrieken