From 06c86e0fc3eec6635fce31b8cd6b988087a8f872 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Sat, 2 Mar 2019 11:14:46 -0800 Subject: [PATCH] syscall: optimize SlicePtrFromStrings MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Instead of allocating a byte slice for every string, calculated the required size and create a single slice big enough to hold all of them. As an added benefit, any error encountered will now be returned before allocations occur. os/exec package benchmarks: name old time/op new time/op delta ExecEcho-8 2.14ms ± 1% 2.14ms ± 3% ~ (p=0.842 n=10+9) name old alloc/op new alloc/op delta ExecEcho-8 6.35kB ± 0% 6.18kB ± 0% -2.65% (p=0.000 n=10+10) name old allocs/op new allocs/op delta ExecEcho-8 69.0 ± 0% 36.0 ± 0% -47.83% (p=0.000 n=10+10) Change-Id: I84118d8473037d873f73903d4e4f6ed14f531ce7 Reviewed-on: https://go-review.googlesource.com/c/164961 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/syscall/exec_unix.go | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/syscall/exec_unix.go b/src/syscall/exec_unix.go index 997ccab07e..4421c449cf 100644 --- a/src/syscall/exec_unix.go +++ b/src/syscall/exec_unix.go @@ -9,6 +9,7 @@ package syscall import ( + "internal/bytealg" "runtime" "sync" "unsafe" @@ -81,15 +82,21 @@ func StringSlicePtr(ss []string) []*byte { // pointers to NUL-terminated byte arrays. If any string contains // a NUL byte, it returns (nil, EINVAL). func SlicePtrFromStrings(ss []string) ([]*byte, error) { - var err error - bb := make([]*byte, len(ss)+1) - for i := 0; i < len(ss); i++ { - bb[i], err = BytePtrFromString(ss[i]) - if err != nil { - return nil, err + n := 0 + for _, s := range ss { + if bytealg.IndexByteString(s, 0) != -1 { + return nil, EINVAL } + n += len(s) + 1 // +1 for NUL + } + bb := make([]*byte, len(ss)+1) + b := make([]byte, n) + n = 0 + for i, s := range ss { + bb[i] = &b[n] + copy(b[n:], s) + n += len(s) + 1 } - bb[len(ss)] = nil return bb, nil } -- 2.50.0