pkg/reference: SplitObject: zero allocations

Before / After:

    BenchmarkSplitObject-10        2785656    428.1 ns/op     416 B/op    13 allocs/op
    BenchmarkSplitObjectNew-10    13510520     88.2 ns/op       0 B/op     0 allocs/op

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2024-06-27 11:44:36 +02:00
parent 799bca97f2
commit 74a6156ac2
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
2 changed files with 34 additions and 4 deletions

View File

@ -157,9 +157,9 @@ func (r Spec) String() string {
// Either may be empty and it is the callers job to validate them // Either may be empty and it is the callers job to validate them
// appropriately. // appropriately.
func SplitObject(obj string) (tag string, dgst digest.Digest) { func SplitObject(obj string) (tag string, dgst digest.Digest) {
parts := strings.SplitAfterN(obj, "@", 2) if i := strings.Index(obj, "@"); i >= 0 {
if len(parts) < 2 { // Offset by one so preserve the "@" in the tag returned.
return parts[0], "" return obj[:i+1], digest.Digest(obj[i+1:])
} }
return parts[0], digest.Digest(parts[1]) return obj, ""
} }

View File

@ -192,3 +192,33 @@ func TestReferenceParser(t *testing.T) {
}) })
} }
} }
func BenchmarkSplitObject(b *testing.B) {
inputs := []string{
"",
"@",
"docker.io@",
"@digest",
"docker.io/library/redis:foo?fooo=asdf",
"docker.io/library/redis:foo@sha256:abcdef?fooo=asdf",
"docker.io/library/redis@sha256:abcdef?fooo=asdf",
"docker.io/library/redis:obj@abcdef?fooo=asdf",
"localhost:5000/library/redis:obj@abcdef?fooo=asdf",
"/docker.io/library/redis:obj@abcdef?fooo=asdf",
"docker.io/library/redis?fooo=asdf",
"sub-dom1.foo.com/bar/baz/quux:latest",
"sub-dom1.foo.com/bar/baz/quux:some-long-tag",
"b.gcr.io/test.example.com/my-app:test.example.com",
"xn--n3h.com/myimage:xn--n3h.com", // ☃.com in punycode
"xn--7o8h.com/myimage:xn--7o8h.com@sha512:fffffff",
"http://xn--7o8h.com/myimage:xn--7o8h.com@sha512:fffffff",
}
b.ReportAllocs()
for i := 0; i < b.N; i++ {
for _, input := range inputs {
_, _ = SplitObject(input)
}
}
}