From 0ef8b510695b5788001832eb0784e85ad99a3df5 Mon Sep 17 00:00:00 2001 From: Kason Braley Date: Fri, 6 Sep 2024 10:02:07 -0700 Subject: [PATCH 1/3] perf(logql): Save 2 allocations in IP filter Preallocate map to save 2 allocations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` goos: darwin goarch: arm64 pkg: github.com/grafana/loki/v3/pkg/logql/log cpu: Apple M2 Pro │ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ _IPFilter/127.0.0.1-10 5.048µ ± 0% 4.591µ ± 1% -9.06% (p=0.002 n=6) _IPFilter/192.168.0.1-192.189.10.12-10 5.082µ ± 0% 4.634µ ± 0% -8.83% (p=0.002 n=6) _IPFilter/192.168.4.5/16-10 4.842µ ± 0% 4.390µ ± 0% -9.35% (p=0.002 n=6) geomean 4.990µ 4.537µ -9.08% │ old.txt │ new.txt │ │ B/op │ B/op vs base │ _IPFilter/127.0.0.1-10 424.0 ± 0% 341.0 ± 0% -19.58% (p=0.002 n=6) _IPFilter/192.168.0.1-192.189.10.12-10 424.5 ± 0% 341.0 ± 0% -19.67% (p=0.002 n=6) _IPFilter/192.168.4.5/16-10 425.0 ± 0% 341.0 ± 0% -19.76% (p=0.002 n=6) geomean 424.5 341.0 -19.67% │ old.txt │ new.txt │ │ allocs/op │ allocs/op vs base │ _IPFilter/127.0.0.1-10 10.000 ± 0% 8.000 ± 0% -20.00% (p=0.002 n=6) _IPFilter/192.168.0.1-192.189.10.12-10 10.000 ± 0% 8.000 ± 0% -20.00% (p=0.002 n=6) _IPFilter/192.168.4.5/16-10 10.000 ± 0% 8.000 ± 0% -20.00% (p=0.002 n=6) geomean 10.00 8.000 -20.00% ``` --- pkg/logql/log/ip.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/logql/log/ip.go b/pkg/logql/log/ip.go index 851cc1a9fa6c..c2fada3681ed 100644 --- a/pkg/logql/log/ip.go +++ b/pkg/logql/log/ip.go @@ -282,7 +282,7 @@ func isHexDigit(r byte) bool { // It returns the number of chars in the initial segment of `s` // which consist only of chars from `accept`. func bytesSpan(s, accept []byte) int { - m := make(map[byte]bool) + m := make(map[byte]bool, len(accept)) for _, r := range accept { m[r] = true From de5ad9d8a2ec024aacb56c0059a1588d81a0b0ca Mon Sep 17 00:00:00 2001 From: Kason Braley Date: Fri, 6 Sep 2024 10:06:59 -0700 Subject: [PATCH 2/3] perf(logql): Use struct for map value to save some bytes Micro-optimization to use a struct instead of bool to save some bytes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` goos: darwin goarch: arm64 pkg: github.com/grafana/loki/v3/pkg/logql/log cpu: Apple M2 Pro │ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ _IPFilter/127.0.0.1-10 4.595µ ± 1% 4.753µ ± 2% +3.44% (p=0.002 n=6) _IPFilter/192.168.0.1-192.189.10.12-10 4.611µ ± 1% 4.608µ ± 1% ~ (p=0.784 n=6) _IPFilter/192.168.4.5/16-10 4.374µ ± 0% 4.339µ ± 0% -0.81% (p=0.002 n=6) geomean 4.525µ 4.563µ +0.84% │ old.txt │ new.txt │ │ B/op │ B/op vs base │ _IPFilter/127.0.0.1-10 341.0 ± 0% 272.0 ± 0% -20.23% (p=0.002 n=6) _IPFilter/192.168.0.1-192.189.10.12-10 341.0 ± 0% 272.0 ± 0% -20.23% (p=0.002 n=6) _IPFilter/192.168.4.5/16-10 341.0 ± 0% 272.0 ± 0% -20.23% (p=0.002 n=6) geomean 341.0 272.0 -20.23% │ old.txt │ new.txt │ │ allocs/op │ allocs/op vs base │ _IPFilter/127.0.0.1-10 8.000 ± 0% 8.000 ± 0% ~ (p=1.000 n=6) ¹ _IPFilter/192.168.0.1-192.189.10.12-10 8.000 ± 0% 8.000 ± 0% ~ (p=1.000 n=6) ¹ _IPFilter/192.168.4.5/16-10 8.000 ± 0% 8.000 ± 0% ~ (p=1.000 n=6) ¹ geomean 8.000 8.000 +0.00% ¹ all samples are equal ``` --- pkg/logql/log/ip.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/logql/log/ip.go b/pkg/logql/log/ip.go index c2fada3681ed..aadbfbd34e90 100644 --- a/pkg/logql/log/ip.go +++ b/pkg/logql/log/ip.go @@ -282,14 +282,14 @@ func isHexDigit(r byte) bool { // It returns the number of chars in the initial segment of `s` // which consist only of chars from `accept`. func bytesSpan(s, accept []byte) int { - m := make(map[byte]bool, len(accept)) + m := make(map[byte]struct{}, len(accept)) for _, r := range accept { - m[r] = true + m[r] = struct{}{} } for i, r := range s { - if !m[r] { + if _, ok := m[r]; !ok { return i } } From 75ca3d8dd74f5acb66a09f50dd9f8d11d093600c Mon Sep 17 00:00:00 2001 From: Kason Braley Date: Fri, 6 Sep 2024 10:43:12 -0700 Subject: [PATCH 3/3] perf(logql): Use array instead of map to save 5 more allocs We can optimize even more here by eliminating the use of the map and opting to use a 256 len array instead for the lookup. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` goos: darwin goarch: arm64 pkg: github.com/grafana/loki/v3/pkg/logql/log cpu: Apple M2 Pro │ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ _IPFilter/127.0.0.1-10 4.609µ ± 1% 3.155µ ± 1% -31.55% (p=0.002 n=6) _IPFilter/192.168.0.1-192.189.10.12-10 4.621µ ± 2% 3.328µ ± 10% -27.98% (p=0.002 n=6) _IPFilter/192.168.4.5/16-10 4.388µ ± 2% 2.947µ ± 1% -32.84% (p=0.002 n=6) geomean 4.538µ 3.139µ -30.82% │ old.txt │ new.txt │ │ B/op │ B/op vs base │ _IPFilter/127.0.0.1-10 272.00 ± 0% 32.00 ± 0% -88.24% (p=0.002 n=6) _IPFilter/192.168.0.1-192.189.10.12-10 272.00 ± 0% 32.00 ± 0% -88.24% (p=0.002 n=6) _IPFilter/192.168.4.5/16-10 272.00 ± 0% 32.00 ± 0% -88.24% (p=0.002 n=6) geomean 272.0 32.00 -88.24% │ old.txt │ new.txt │ │ allocs/op │ allocs/op vs base │ _IPFilter/127.0.0.1-10 8.000 ± 0% 3.000 ± 0% -62.50% (p=0.002 n=6) _IPFilter/192.168.0.1-192.189.10.12-10 8.000 ± 0% 3.000 ± 0% -62.50% (p=0.002 n=6) _IPFilter/192.168.4.5/16-10 8.000 ± 0% 3.000 ± 0% -62.50% (p=0.002 n=6) geomean 8.000 3.000 -62.50% ``` --- pkg/logql/log/ip.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/logql/log/ip.go b/pkg/logql/log/ip.go index aadbfbd34e90..c02c0a0ab306 100644 --- a/pkg/logql/log/ip.go +++ b/pkg/logql/log/ip.go @@ -282,14 +282,14 @@ func isHexDigit(r byte) bool { // It returns the number of chars in the initial segment of `s` // which consist only of chars from `accept`. func bytesSpan(s, accept []byte) int { - m := make(map[byte]struct{}, len(accept)) + var charset [256]bool for _, r := range accept { - m[r] = struct{}{} + charset[r] = true } for i, r := range s { - if _, ok := m[r]; !ok { + if !charset[r] { return i } }