bisect를 이용한 확장 기능 문제 해결
2021년 2월 16일 Johannes Rieken, @johannesrieken 작성
"git-bisect와 같지만, VS Code 확장 기능용입니다."
Visual Studio Code의 진정한 힘은 확장 기능에 있습니다: 테마 확장 기능은 색상과 아이콘을 추가하고, 언어 확장 기능은 스마트 코드 완성(IntelliSense)과 탐색을 가능하게 하며, 디버거 확장 기능은 코드를 실행하고 버그를 쉽게 찾을 수 있게 합니다. 음악을 연주하는 확장 기능도 있고, 주식 시세를 보여주는 확장 기능도 있으며, 여러 지역과 시간대에 걸쳐 협업을 가능하게 하는 확장 기능도 있습니다. VS Code Marketplace에는 28,000개 이상의 확장 기능이 있으며, 사용자가 50개 이상의 확장 기능을 설치하는 것은 드문 일이 아닙니다. 이렇게 많은 확장 기능이 있다면 버그는 피할 수 없습니다. 부인하는 대신, 문제 해결을 쉽게 만들고 싶습니다.
"나쁜" 확장 기능
저희는 확장 기능을 사랑하며 실제로 "나쁜" 확장 기능은 없다고 생각합니다. 그러나 다른 모든 소프트웨어와 마찬가지로 확장 기능에도 버그와 기능 격차가 있습니다. 따라서 가독성과 극적인 효과를 위해, 충돌을 일으키거나 원치 않는 동작을 표시할 수 있는 확장 기능을 "나쁜 확장 기능"이라고 부르겠습니다. 다행히도 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가 한 단계를 더(log2(N) + 1) 수행한다고 느낄 수 있습니다. 이는 첫 번째 라운드에서 모든 확장 기능을 비활성화하고 시작하기 때문입니다. 이 첫 번째 단계는 VS Code 자체로 인해 문제가 발생했을 수 있으며 확장 기능 때문이 아닐 수 있고, 불필요하게 복잡한 상황으로 몰아가는 것을 방지하기 위함입니다.
이상입니다. 확장 기능 bisect를 사용할 일이 없기를 바랍니다. 그러나 확장 기능과 관련이 있을 수 있는 문제에 직면하게 된다면, 문제 해결을 더 쉽고, 빠르고, 즐겁게 만들 수 있기를 바랍니다.
행복한 코딩 되세요,
Johannes Rieken, VS Code 수석 소프트웨어 엔지니어 @johannesrieken