🚀 在 VS Code 中

使用二分法解決擴充功能問題

作者:Johannes Rieken,2021 年 2 月 16 日,@johannesrieken

「就像 git-bisect,但適用於 VS Code 擴充功能。」

Visual Studio Code 的真正強大之處在於其擴充功能:佈景主題擴充功能新增色彩和圖示,語言擴充功能啟用智慧程式碼完成 (IntelliSense) 和導覽,偵錯工具擴充功能讓您能夠執行程式碼並輕鬆尋找錯誤。有些擴充功能可以播放音樂、有些可以顯示股票行情,還有一些擴充功能可以跨地點和時區實現協同工作。VS Code Marketplace 託管超過 28,000 個擴充功能,使用者安裝 50 個或更多擴充功能並不罕見。有這麼多擴充功能,錯誤是不可避免的。我們不想否認,而是希望讓疑難排解變得容易。

「不良」擴充功能

我們喜歡擴充功能,而且真的不認為有任何「不良」擴充功能。但是,與所有軟體一樣,擴充功能也有錯誤和功能缺陷。因此,為了方便閱讀和人為的戲劇效果,讓我們使用「不良擴充功能」這個詞,指的是可能會當機或只是顯示不必要行為的擴充功能。幸運的是,我們在設計 VS Code 時就考慮到「不良」擴充功能,因此將它們在單獨的程序中執行。這種隔離確保 VS Code 持續執行、游標始終閃爍,而且您始終可以儲存您的工作。

為了好玩,並且為了更容易示範擴充功能二分法,我們建立並發布了 Extension Bisect Demo 擴充功能。安裝後,每當您遇到「bisect」這個詞時,它都會惱人地重設您的游標。您可以使用此擴充功能來跟隨這篇部落格文章的步驟。

以困難的方式尋找「不良」擴充功能

今天,尋找「不良」擴充功能可能很容易也可能很困難。開啟 [擴充功能] 檢視 (⇧⌘X (Windows、Linux Ctrl+Shift+X)),停用擴充功能,重新載入視窗 (開發人員:重新載入視窗),並檢查問題是否仍然存在。如果問題已消失,則該擴充功能是「不良」的,您就完成了。否則,重新啟用該擴充功能,並對下一個擴充功能重複此程序。

Disabling an extension step by step

如果您幸運,第一個擴充功能就是「不良」的;如果您不幸運,則是最後一個擴充功能。使用電腦科學語言來說,這表示使用 N 個擴充功能,您在最糟情況下需要重複此程序 O(N) (順序 N) 次,平均情況下需要 O(N/2) 次。由於此演算法是由人類 (您) 操作,即使是小的 N 值也很費力。這就是 擴充功能二分法 公用程式派上用場的地方。它在最糟和平均情況下都好得多,因為它會以對半的方式停用擴充功能。

歡迎使用擴充功能二分法

VS Code 中的擴充功能二分法公用程式的靈感來自 git bisect 命令。對於熟悉 Git 的人來說,此命令有助於找出儲存庫中哪個提交引入了問題。

讓我們使用一個範例:我安裝了 24 個擴充功能,而第 8 個擴充功能是「不良」的。我們知道迭代方法需要 8 個步驟。那麼二分法呢?

以下影片顯示透過說明:開始擴充功能二分法命令啟動擴充功能二分法,然後選取現在良好這是錯誤的,直到識別出「不良」擴充功能。一旦識別出來,您可以選擇為該擴充功能回報問題。

The extension bisect process

以下逐步說明如何找到「不良」擴充功能

  1. 二分法將 24 個擴充功能分成兩個各 12 個擴充功能的一半,並停用後半部的所有 12 個擴充功能。
  2. 在此範例中,第 8 個擴充功能是「不良」的,因此它位於前半部且未停用。事情仍然沒有像我們預期的那樣運作。由於問題仍然存在,擴充功能二分法重複此程序,將前半部的 12 個擴充功能分成兩個部分:6 個已啟用,6 個已停用。所有其他擴充功能也會重新啟用。
  3. 第 8 個擴充功能現在已停用。事情現在很好。這表示二分法可以繼續在後半部 (擴充功能 6-11) 進行,並將它們分成 3 個已啟用和 3 個已停用的擴充功能。
  4. 現在,第 8 個擴充功能已重新啟用,問題再次出現。這表示二分法繼續在前半部進行。它將它們分成 1 個已啟用和 2 個已停用的擴充功能。
  5. 第 8 個擴充功能現在已停用,事情再次良好,二分法繼續在後半部進行,將其分成 1 個已啟用和 1 個已停用的擴充功能。
  6. 第 8 個擴充功能是唯一停用的擴充功能,問題已消失。這表示我們已找到「不良」擴充功能,並且我們已完成。

更快速地疑難排解

我們看到,在每個步驟中,二分法都會將搜尋空間縮減一半。現在它以對數時間執行步驟,導致平均和最糟情況下的效能為 O(log N)。這非常好,因為它具有良好的擴充性。使用 24 個擴充功能,您需要 4 到 5 個步驟來找到「不良」擴充功能,使用 38 個擴充功能,則只需要多 1 個步驟。但是,最佳情況更糟,因為使用迭代方法,您可能會很幸運地在第一輪中找到「不良」擴充功能。

請記住,擴充功能二分法依賴您提供正確的回饋。您可能會輕易地愚弄它,以及您自己,方法是始終回答現在良好 (歸咎於最後一個擴充功能) 或這是錯誤的 (找不到擴充功能)。

另一個有用的見解是,擴充功能二分法開始時會考慮已啟用擴充功能的完整清單。這表示您可以透過在啟動之前停用已知的「良好」擴充功能,並在啟動之後重新啟用它,將其從二分法中排除。但是,僅當您確定該擴充功能不是「不良」擴充功能時才執行此操作。

最後,您可能會注意到二分法需要額外的步驟 (log2(N) + 1)。那是因為它在第一輪開始時會停用所有擴充功能。執行此第一步的原因是您可能會看到的問題是由 VS Code 本身引起的,而不是由擴充功能引起的,而且我們不想不必要地讓您鑽牛角尖。

就是這樣。我們希望您永遠不需要使用擴充功能二分法。但是,如果您確實遇到可能與擴充功能相關的問題,那麼我們希望我們可以讓疑難排解變得更輕鬆、更快速且更愉快。

祝您編碼愉快,

Johannes Rieken,VS Code 首席軟體工程師 @johannesrieken