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 (
hasher = sha256.New()
sumBuffer [sha256.Size]byte
hasher = sha256.New()
sumBuffer [sha256.Size]byte
b64SumBuffer [44]byte // base64's EncodedLen on sha256.Size (32) with no padding
)
// addGarbleToHash takes some arbitrary input bytes,
@ -232,37 +233,36 @@ func hashWith(salt []byte, name string) string {
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]
nameBase64.Encode(b64SumBuffer[:], hasher.Sum(sumBuffer[:0]))
b64Name := b64SumBuffer[:hashLength]
// 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.
if isDigit(sum[0]) {
if isDigit(b64Name[0]) {
// Turn "3foo" into "Dfoo".
// Similar to toLower, since uppercase letters go after digits
// in the ASCII table.
sum[0] += 'A' - '0'
b64Name[0] += 'A' - '0'
}
// Keep the result equally exported or not, if it was an identifier.
if !token.IsIdentifier(name) {
return string(sum)
return string(b64Name)
}
if token.IsExported(name) {
if sum[0] == '_' {
if b64Name[0] == '_' {
// Turn "_foo" into "Zfoo".
sum[0] = 'Z'
} else if isLower(sum[0]) {
b64Name[0] = 'Z'
} else if isLower(b64Name[0]) {
// Turn "afoo" into "Afoo".
sum[0] = toUpper(sum[0])
b64Name[0] = toUpper(b64Name[0])
}
} else {
if isUpper(sum[0]) {
if isUpper(b64Name[0]) {
// 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.

Loading…
Cancel
Save