perf: add fast path for simple recursive globs#2884
Conversation
| return nil, false, nil | ||
| } | ||
|
|
||
| results := make(map[string]bool) |
There was a problem hiding this comment.
Possibly use a slice rather than map.
var results []string
....
matched, _ := filepath.Match(namePattern, d.Name()) // d.Name() is faster than filepath.Base(path)
if !matched {
return nil
}
results = append(results, path)
return nil
...
return results, true, nil
|
About twice as fast, right? Or do I read the results incorrectly. |
|
I wondered why Make is so fast ... and after some lazy prompting ... got some kind of idea. Basically, cache the globing on the first run, and then do os.Stat calls against that cache for subsequent calls. Could be an idea? |
andreynering
left a comment
There was a problem hiding this comment.
Hey @Napolitain
I added a comment below. Can you take a look and rebase with main?
| return collectKeys(results), nil | ||
| } | ||
|
|
||
| func fastRecursiveGlob(pattern string) ([]string, bool, error) { |
There was a problem hiding this comment.
We have a package dedicated to filesystem functions: internal/fsext.
I propose that we move this function there as a new internal/fsext/glob.go file.
If easy enough, a test for this function would be nice as well.
There was a problem hiding this comment.
I moved the fast recursive glob implementation to internal/fsext/glob.go and added tests.
a61a3b9 to
d2b399a
Compare
Recognize literal-root recursive patterns such as path/to/folder/**/*.yaml and expand them with filepath.WalkDir plus filepath.Match. Keep complex shell patterns and symlinked directories on the existing mvdan shell expander while preserving post-expansion gitignore filtering. Verification: go test ./...; golangci-lint run
Move simple recursive glob expansion into the shared internal filesystem package and keep fingerprinting as its caller. Add focused tests for direct and nested matches, unsupported patterns, non-directory roots, and symlinked-directory fallback.
Accumulate WalkDir matches directly in a slice and compare the filename pattern against DirEntry.Name. WalkDir yields each path once, so the fast path can remove its deduplication map and sort the normalized result slice before returning.
d2b399a to
a0d07ac
Compare
This is a stacked optimization PR on top of the filesystem benchmark work in #2881. Please review or merge #2881 first; this branch intentionally depends on those benchmarks so the performance impact can be evaluated with the same many-small and few-large fixtures.
This is independent from #2883.
This PR optimizes expansion for simple recursive source globs like
path/to/folder/**/*.yaml.The fast path only handles narrow literal-root recursive globs. More complex shell-style patterns continue to use the existing expander, and symlinked directories fall back to the existing path to preserve current behavior.