From cdc1efd95b7133cf2c158c65d86a99fff07d6104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 12 Feb 2022 18:45:33 +0000 Subject: [PATCH] avoid allocating twice for every name we hash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit name old time/op new time/op delta Build-16 9.25s ± 2% 9.26s ± 3% ~ (p=0.841 n=5+5) name old bin-B new bin-B delta Build-16 5.16M ± 0% 5.16M ± 0% ~ (all equal) name old cached-time/op new cached-time/op delta Build-16 316ms ± 5% 314ms ± 5% ~ (p=1.000 n=5+5) name old mallocs/op new mallocs/op delta Build-16 30.7M ± 0% 29.8M ± 0% -2.90% (p=0.008 n=5+5) name old sys-time/op new sys-time/op delta Build-16 4.78s ± 4% 4.70s ± 4% ~ (p=0.690 n=5+5) --- hash.go | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/hash.go b/hash.go index ae3fe57..18fa583 100644 --- a/hash.go +++ b/hash.go @@ -75,6 +75,11 @@ func alterToolVersion(tool string, args []string) error { return nil } +var ( + hasher = sha256.New() + sumBuffer [sha256.Size]byte +) + // addGarbleToHash takes some arbitrary input bytes, // typically a hash such as an action ID or a content ID, // and returns a new hash which also contains garble's own deterministic inputs. @@ -85,21 +90,24 @@ func addGarbleToHash(inputHash []byte) []byte { // Join the two content IDs together into a single base64-encoded sha256 // sum. This includes the original tool's content ID, and garble's own // content ID. - h := sha256.New() - h.Write(inputHash) + hasher.Reset() + hasher.Write(inputHash) if len(cache.BinaryContentID) == 0 { panic("missing binary content ID") } - h.Write(cache.BinaryContentID) + hasher.Write(cache.BinaryContentID) // We also need to add the selected options to the full version string, // because all of them result in different output. We use spaces to // separate the env vars and flags, to reduce the chances of collisions. if cache.GOGARBLE != "" { - fmt.Fprintf(h, " GOGARBLE=%s", cache.GOGARBLE) + fmt.Fprintf(hasher, " GOGARBLE=%s", cache.GOGARBLE) } - appendFlags(h, true) - return h.Sum(nil)[:buildIDComponentLength] + appendFlags(hasher, true) + // addGarbleToHash returns the sum buffer, so we need a new copy. + // Otherwise the next use of the global sumBuffer would conflict. + sumBuffer := make([]byte, 0, sha256.Size) + return hasher.Sum(sumBuffer)[:buildIDComponentLength] } // appendFlags writes garble's own flags to w in string form. @@ -220,12 +228,12 @@ func hashWith(salt []byte, name string) string { // thousands of obfuscated names. const hashLength = 8 - d := sha256.New() - d.Write(salt) - d.Write(flagSeed.bytes) - io.WriteString(d, name) - sum := make([]byte, nameBase64.EncodedLen(d.Size())) - nameBase64.Encode(sum, d.Sum(nil)) + hasher.Reset() + hasher.Write(salt) + hasher.Write(flagSeed.bytes) + io.WriteString(hasher, name) + sum := make([]byte, nameBase64.EncodedLen(hasher.Size())) + nameBase64.Encode(sum, hasher.Sum(sumBuffer[:0])) sum = sum[:hashLength] // Even if we are hashing a package path, we still want the result to be @@ -269,11 +277,11 @@ func gocachePathForFile(path string) (string, error) { } defer f.Close() - h := sha256.New() - if _, err := io.Copy(h, f); err != nil { + hasher.Reset() + if _, err := io.Copy(hasher, f); err != nil { return "", err } - sum := hex.EncodeToString(h.Sum(nil)) + sum := hex.EncodeToString(hasher.Sum(sumBuffer[:0])) entry := filepath.Join(cache.GoEnv.GOCACHE, sum[:2], sum+"-d") // Ensure the file actually exists in the build cache.