Skip to content

Commit 4dadcd2

Browse files
authored
Improve performance with large numbers of untracked or modified files (#3919)
- **PR Description** **BuildTreeFromFiles** used a linear complexity lookup to find if the children has already been added. Use maps to get constant time lookup for children. For the test scenario in #3798 (90000 untracked files) this reduces the time of BuildTreeFromFiles from something like 10s down to about 30ms on my machine. Fixes #3798. - **Please check if the PR fulfills these requirements** * [x] Cheatsheets are up-to-date (run `go generate ./...`) * [x] Code has been formatted (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#code-formatting)) * [ ] Tests have been added/updated (see [here](https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md) for the integration test guide) * [ ] Text is internationalised (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#internationalisation)) * [ ] If a new UserConfig entry was added, make sure it can be hot-reloaded (see [here](https://github.com/jesseduffield/lazygit/blob/master/docs/dev/Codebase_Guide.md#using-userconfig)) * [ ] Docs have been updated if necessary * [x] You've read through your own file changes for silly mistakes etc <!-- Be sure to name your PR with an imperative e.g. 'Add worktrees view' see https://github.com/jesseduffield/lazygit/releases/tag/v0.40.0 for examples -->
2 parents c67979a + b18f12c commit 4dadcd2

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

Diff for: pkg/gui/filetree/build_tree.go

+17-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
func BuildTreeFromFiles(files []*models.File) *Node[models.File] {
1111
root := &Node[models.File]{}
1212

13+
childrenMapsByNode := make(map[*Node[models.File]]map[string]*Node[models.File])
14+
1315
var curr *Node[models.File]
1416
for _, file := range files {
1517
splitPath := split(file.Name)
@@ -23,11 +25,19 @@ func BuildTreeFromFiles(files []*models.File) *Node[models.File] {
2325
}
2426

2527
path := join(splitPath[:i+1])
26-
for _, existingChild := range curr.Children {
27-
if existingChild.Path == path {
28-
curr = existingChild
29-
continue outer
30-
}
28+
29+
var currNodeChildrenMap map[string]*Node[models.File]
30+
var isCurrNodeMapped bool
31+
32+
if currNodeChildrenMap, isCurrNodeMapped = childrenMapsByNode[curr]; !isCurrNodeMapped {
33+
currNodeChildrenMap = make(map[string]*Node[models.File])
34+
childrenMapsByNode[curr] = currNodeChildrenMap
35+
}
36+
37+
child, doesCurrNodeHaveChildAlready := currNodeChildrenMap[path]
38+
if doesCurrNodeHaveChildAlready {
39+
curr = child
40+
continue outer
3141
}
3242

3343
newChild := &Node[models.File]{
@@ -36,6 +46,8 @@ func BuildTreeFromFiles(files []*models.File) *Node[models.File] {
3646
}
3747
curr.Children = append(curr.Children, newChild)
3848

49+
currNodeChildrenMap[path] = newChild
50+
3951
curr = newChild
4052
}
4153
}

0 commit comments

Comments
 (0)