From 86181120bd664e195dee7f62b71771b302cc59bc Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Thu, 12 Apr 2018 12:15:58 -0700 Subject: [PATCH] os: allocate buffer lazily in Expand MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit As an example of why this might happen, consider this code from cmd/internal/objfile: // Expand literal "$GOROOT" rewritten by obj.AbsFile() filename = filepath.Clean(os.ExpandEnv(filename)) In this case, filename might not contain "$GOROOT", in which case we can skip the buffer entirely. name old time/op new time/op delta Expand/noop-8 46.7ns ± 1% 12.9ns ± 1% -72.47% (p=0.000 n=9+9) Expand/multiple-8 139ns ± 1% 137ns ± 1% -1.36% (p=0.001 n=10+10) The Expand/multiple improvement is probably noise. This speeds up cmd/objdump detectably, if not much. Using "benchcmd ObjdumpCompile go tool objdump `go tool -n compile`": name old time/op new time/op delta ObjdumpCompile 9.35s ± 2% 9.07s ± 3% -3.00% (p=0.000 n=18+18) Updates #24725 Change-Id: Id31ec6a9b8dfb3c0f1db58fe1f958e11c39e656c Reviewed-on: https://go-review.googlesource.com/106697 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/os/env.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/os/env.go b/src/os/env.go index b3b615cb33..544c03446f 100644 --- a/src/os/env.go +++ b/src/os/env.go @@ -14,11 +14,14 @@ import ( // Expand replaces ${var} or $var in the string based on the mapping function. // For example, os.ExpandEnv(s) is equivalent to os.Expand(s, os.Getenv). func Expand(s string, mapping func(string) string) string { - buf := make([]byte, 0, 2*len(s)) + var buf []byte // ${} is all ASCII, so bytes are fine for this operation. i := 0 for j := 0; j < len(s); j++ { if s[j] == '$' && j+1 < len(s) { + if buf == nil { + buf = make([]byte, 0, 2*len(s)) + } buf = append(buf, s[i:j]...) name, w := getShellName(s[j+1:]) // If the name is empty, keep the $. @@ -31,6 +34,9 @@ func Expand(s string, mapping func(string) string) string { i = j + 1 } } + if buf == nil { + return s + } return string(buf) + s[i:] } -- 2.48.1