From bbbe48aaadf7f63896f28373cd0691da19f09293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sun, 26 May 2024 15:41:59 +0100 Subject: [PATCH] expand: replace sort.SearchStrings with slices.BinarySearchFunc Making use of generics, and using fewer comparisons for big slices. --- expand/environ.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/expand/environ.go b/expand/environ.go index 98cc748e..17645119 100644 --- a/expand/environ.go +++ b/expand/environ.go @@ -4,9 +4,9 @@ package expand import ( + "cmp" "runtime" "slices" - "sort" "strings" ) @@ -205,10 +205,23 @@ func listEnvironWithUpper(upper bool, pairs ...string) Environ { type listEnviron []string func (l listEnviron) Get(name string) Variable { - prefix := name + "=" - i := sort.SearchStrings(l, prefix) - if i < len(l) && strings.HasPrefix(l[i], prefix) { - return Variable{Exported: true, Kind: String, Str: strings.TrimPrefix(l[i], prefix)} + eqpos := len(name) + endpos := len(name) + 1 + i, ok := slices.BinarySearchFunc(l, name, func(l, name string) int { + if len(l) < endpos { + // Too short; see if we are before or after the name. + return strings.Compare(l, name) + } + // Compare the name prefix, then the equal character. + c := strings.Compare(l[:eqpos], name) + eq := l[eqpos] + if c == 0 { + return cmp.Compare(eq, '=') + } + return c + }) + if ok { + return Variable{Exported: true, Kind: String, Str: l[i][endpos:]} } return Variable{} }