remove another allocation per hashed name

We use a buffer to turn a hash into a name via base64.
We can reuse that buffer to save one repeated allocation.
The returned value is still unique, as we convert to a string.

	name      old time/op         new time/op         delta
	Build-16          9.26s ± 3%          9.39s ± 2%    ~     (p=0.151 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          314ms ± 5%          324ms ± 6%    ~     (p=0.310 n=5+5)

	name      old mallocs/op      new mallocs/op      delta
	Build-16          29.8M ± 0%          29.4M ± 0%  -1.38%  (p=0.008 n=5+5)

	name      old sys-time/op     new sys-time/op     delta
	Build-16          4.70s ± 4%          4.66s ± 2%    ~     (p=0.548 n=5+5)
pull/482/head
Daniel Martí 3 years ago committed by Andrew LeFevre
parent cdc1efd95b
commit cffb5acd11

@ -76,8 +76,9 @@ func alterToolVersion(tool string, args []string) error {
} }
var ( var (
hasher = sha256.New() hasher = sha256.New()
sumBuffer [sha256.Size]byte sumBuffer [sha256.Size]byte
b64SumBuffer [44]byte // base64's EncodedLen on sha256.Size (32) with no padding
) )
// addGarbleToHash takes some arbitrary input bytes, // addGarbleToHash takes some arbitrary input bytes,
@ -232,37 +233,36 @@ func hashWith(salt []byte, name string) string {
hasher.Write(salt) hasher.Write(salt)
hasher.Write(flagSeed.bytes) hasher.Write(flagSeed.bytes)
io.WriteString(hasher, name) io.WriteString(hasher, name)
sum := make([]byte, nameBase64.EncodedLen(hasher.Size())) nameBase64.Encode(b64SumBuffer[:], hasher.Sum(sumBuffer[:0]))
nameBase64.Encode(sum, hasher.Sum(sumBuffer[:0])) b64Name := b64SumBuffer[:hashLength]
sum = sum[:hashLength]
// Even if we are hashing a package path, we still want the result to be // Even if we are hashing a package path, we still want the result to be
// a valid identifier, since we'll use it as the package name too. // a valid identifier, since we'll use it as the package name too.
if isDigit(sum[0]) { if isDigit(b64Name[0]) {
// Turn "3foo" into "Dfoo". // Turn "3foo" into "Dfoo".
// Similar to toLower, since uppercase letters go after digits // Similar to toLower, since uppercase letters go after digits
// in the ASCII table. // in the ASCII table.
sum[0] += 'A' - '0' b64Name[0] += 'A' - '0'
} }
// Keep the result equally exported or not, if it was an identifier. // Keep the result equally exported or not, if it was an identifier.
if !token.IsIdentifier(name) { if !token.IsIdentifier(name) {
return string(sum) return string(b64Name)
} }
if token.IsExported(name) { if token.IsExported(name) {
if sum[0] == '_' { if b64Name[0] == '_' {
// Turn "_foo" into "Zfoo". // Turn "_foo" into "Zfoo".
sum[0] = 'Z' b64Name[0] = 'Z'
} else if isLower(sum[0]) { } else if isLower(b64Name[0]) {
// Turn "afoo" into "Afoo". // Turn "afoo" into "Afoo".
sum[0] = toUpper(sum[0]) b64Name[0] = toUpper(b64Name[0])
} }
} else { } else {
if isUpper(sum[0]) { if isUpper(b64Name[0]) {
// Turn "Afoo" into "afoo". // Turn "Afoo" into "afoo".
sum[0] = toLower(sum[0]) b64Name[0] = toLower(b64Name[0])
} }
} }
return string(sum) return string(b64Name)
} }
// gocachePathForFile works out the path an object file will take in GOCACHE. // gocachePathForFile works out the path an object file will take in GOCACHE.

Loading…
Cancel
Save