Improving performance of tree traversal on getViewState function #115387
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Optimising getViewState tree traversal to improve performance on folders with too many children.
Context
We are currently running VSCode in a monorepo folder that has hundreds of thousands of subfolders/files. There are a few performance issues happening due to that and the getViewState has been identified as one of them.
Problem
Whenever a folder was opened, such as branches (88K children), the UI would freeze when opening new folders, changing tabs and also every few seconds. The reason for that was because the
onWillSaveWorkspaceis called every few secs and whenever VSCode becomes the active tab to save the list of folders that are expanded in storage so the user can refresh the page and still have their expanded folders open.The issue was that the
getViewState()function that returns a list of expanded folders was traversing the tree too slowly.Solution
In this case, it does not matter by which order we traverse the tree to get all states. Array.shift() has O(n) performance while Array.pop() has O(1), therefore, changing it to pop makes it N times faster.
In the image below you can see that after changing from BFS traversal to DFS, the function improved from an average of 4.5 seconds to 4 milliseconds for the monorepo that contains a folder with a 100K children.
Before:

After:
