Skip to content

Commit

Permalink
Improve performance with large numbers of untracked or modified files (
Browse files Browse the repository at this point in the history
…#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
-->
  • Loading branch information
stefanhaller authored Sep 18, 2024
2 parents c67979a + b18f12c commit 4dadcd2
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions pkg/gui/filetree/build_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
func BuildTreeFromFiles(files []*models.File) *Node[models.File] {
root := &Node[models.File]{}

childrenMapsByNode := make(map[*Node[models.File]]map[string]*Node[models.File])

var curr *Node[models.File]
for _, file := range files {
splitPath := split(file.Name)
Expand All @@ -23,11 +25,19 @@ func BuildTreeFromFiles(files []*models.File) *Node[models.File] {
}

path := join(splitPath[:i+1])
for _, existingChild := range curr.Children {
if existingChild.Path == path {
curr = existingChild
continue outer
}

var currNodeChildrenMap map[string]*Node[models.File]
var isCurrNodeMapped bool

if currNodeChildrenMap, isCurrNodeMapped = childrenMapsByNode[curr]; !isCurrNodeMapped {
currNodeChildrenMap = make(map[string]*Node[models.File])
childrenMapsByNode[curr] = currNodeChildrenMap
}

child, doesCurrNodeHaveChildAlready := currNodeChildrenMap[path]
if doesCurrNodeHaveChildAlready {
curr = child
continue outer
}

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

currNodeChildrenMap[path] = newChild

curr = newChild
}
}
Expand Down

0 comments on commit 4dadcd2

Please sign in to comment.