From 17c53efb0d4d9e0f38ba91231a92dea27315d3c5 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Wed, 7 Oct 2020 15:51:17 +0200 Subject: [PATCH] filter: Optimize double wildcard expansion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This only allocates a single slice to expand the double wildcard and only copies the pattern prefix once. name old time/op new time/op delta FilterPatterns/Relative-4 22.7ms ± 5% 23.3ms ± 9% ~ (p=0.353 n=10+10) FilterPatterns/Absolute-4 14.2ms ±13% 13.9ms ± 7% ~ (p=0.853 n=10+10) FilterPatterns/Wildcard-4 266ms ±16% 51ms ± 7% -80.67% (p=0.000 n=10+9) FilterPatterns/ManyNoMatch-4 554ms ± 6% 551ms ± 9% ~ (p=0.436 n=10+10) name old alloc/op new alloc/op delta FilterPatterns/Relative-4 3.57MB ± 0% 3.57MB ± 0% ~ (p=0.349 n=10+10) FilterPatterns/Absolute-4 3.57MB ± 0% 3.57MB ± 0% ~ (p=0.073 n=10+9) FilterPatterns/Wildcard-4 141MB ± 0% 14MB ± 0% -89.89% (p=0.000 n=10+9) FilterPatterns/ManyNoMatch-4 3.57MB ± 0% 3.57MB ± 0% ~ (all equal) name old allocs/op new allocs/op delta FilterPatterns/Relative-4 22.2k ± 0% 22.2k ± 0% ~ (all equal) FilterPatterns/Absolute-4 22.2k ± 0% 22.2k ± 0% ~ (all equal) FilterPatterns/Wildcard-4 1.63M ± 0% 0.09M ± 0% -94.56% (p=0.000 n=10+10) FilterPatterns/ManyNoMatch-4 22.2k ± 0% 22.2k ± 0% ~ (all equal) --- internal/filter/filter.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/internal/filter/filter.go b/internal/filter/filter.go index cb4fb1702..5eb119f49 100644 --- a/internal/filter/filter.go +++ b/internal/filter/filter.go @@ -123,11 +123,15 @@ func hasDoubleWildcard(list Pattern) (ok bool, pos int) { func match(patterns Pattern, strs []string) (matched bool, err error) { if ok, pos := hasDoubleWildcard(patterns); ok { // gradually expand '**' into separate wildcards + newPat := make(Pattern, len(strs)) + // copy static prefix once + copy(newPat, patterns[:pos]) for i := 0; i <= len(strs)-len(patterns)+1; i++ { - newPat := make(Pattern, pos) - copy(newPat, patterns[:pos]) - for k := 0; k < i; k++ { - newPat = append(newPat, "*") + // limit to static prefix and already appended '*' + newPat := newPat[:pos+i] + // in the first iteration the wildcard expands to nothing + if i > 0 { + newPat[pos+i-1] = "*" } newPat = append(newPat, patterns[pos+1:]...)