pkg/stringid: optimize performance

Had these laying around; not very critical as these functions are barely
used, but probably won't hurt:

    BenchmarkIsShortID-10       1447230     816.9 ns/op       0 B/op     0 allocs/op
    BenchmarkIsShortIDNew-10   10103319     101.9 ns/op       0 B/op     0 allocs/op
    BenchmarkValidateID-10        10000    112208 ns/op   33005 B/op    10 allocs/op
    BenchmarkValidateIDNew-10    653293      1737 ns/op   16534 B/op     6 allocs/op

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2022-12-16 14:44:52 +01:00
parent 5f1938f545
commit 54512f2184
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
2 changed files with 42 additions and 7 deletions

View file

@ -4,21 +4,28 @@ package stringid // import "github.com/docker/docker/pkg/stringid"
import ( import (
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"fmt" "errors"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
) )
const shortLen = 12 const (
shortLen = 12
fullLen = 64
)
var ( var (
validShortID = regexp.MustCompile("^[a-f0-9]{12}$") validShortID = regexp.MustCompile("^[a-f0-9]{12}$")
validHex = regexp.MustCompile(`^[a-f0-9]{64}$`) validHex = regexp.MustCompile(`^[a-f0-9]{64}$`)
) )
// IsShortID determines if an arbitrary string *looks like* a short ID. // IsShortID determines if id has the correct format and length for a short ID.
// It checks the IDs length and if it consists of valid characters for IDs (a-f0-9).
func IsShortID(id string) bool { func IsShortID(id string) bool {
if len(id) != shortLen {
return false
}
return validShortID.MatchString(id) return validShortID.MatchString(id)
} }
@ -54,10 +61,13 @@ func GenerateRandomID() string {
} }
} }
// ValidateID checks whether an ID string is a valid image ID. // ValidateID checks whether an ID string is a valid, full-length image ID.
func ValidateID(id string) error { func ValidateID(id string) error {
if ok := validHex.MatchString(id); !ok { if len(id) != fullLen {
return fmt.Errorf("image ID %q is invalid", id) return errors.New("image ID '" + id + "' is invalid")
}
if !validHex.MatchString(id) {
return errors.New("image ID '" + id + "' is invalid")
} }
return nil return nil
} }

View file

@ -8,7 +8,7 @@ import (
func TestGenerateRandomID(t *testing.T) { func TestGenerateRandomID(t *testing.T) {
id := GenerateRandomID() id := GenerateRandomID()
if len(id) != 64 { if len(id) != fullLen {
t.Fatalf("Id returned is incorrect: %s", id) t.Fatalf("Id returned is incorrect: %s", id)
} }
} }
@ -62,3 +62,28 @@ func TestIsShortIDNotCorrectSize(t *testing.T) {
t.Fatalf("%s is not a short ID", id) t.Fatalf("%s is not a short ID", id)
} }
} }
var testIDs = []string{
"4e38e38c8ce0",
strings.Repeat("a", shortLen+1),
strings.Repeat("a", 16000),
"90435eec5c4e124e741ef731e118be2fc799a68aba0466ec17717f24ce2ae6a2",
}
func BenchmarkIsShortID(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
for _, id := range testIDs {
_ = IsShortID(id)
}
}
}
func BenchmarkValidateID(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
for _, id := range testIDs {
_ = ValidateID(id)
}
}
}