util/fastuuid: add a more efficient uuid generator
This still generates github.com/google/uuid UUID objects, but does so using a ChaCha8 CSPRNG from the stdlib rand/v2 package. The public API is backed by a sync.Pool to provide good performance in highly concurrent operation. Under high load the read API produces a lot of extra garbage and overhead by way of temporaries and syscalls. This implementation reduces both to minimal levels, and avoids any long held global lock by utilizing sync.Pool. Updates tailscale/corp#18266 Updates tailscale/corp#19054 Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:

committed by
James Tucker

parent
db760d0bac
commit
d0f3fa7d7e
72
util/fastuuid/fastuuid_test.go
Normal file
72
util/fastuuid/fastuuid_test.go
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package fastuuid
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func TestNewUUID(t *testing.T) {
|
||||
g := pool.Get().(*generator)
|
||||
defer pool.Put(g)
|
||||
u := g.newUUID()
|
||||
if u[6] != (u[6]&0x0f)|0x40 {
|
||||
t.Errorf("version bits are incorrect")
|
||||
}
|
||||
if u[8] != (u[8]&0x3f)|0x80 {
|
||||
t.Errorf("variant bits are incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBasic(b *testing.B) {
|
||||
b.Run("NewUUID", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NewUUID()
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("uuid.New-unpooled", func(b *testing.B) {
|
||||
uuid.DisableRandPool()
|
||||
for i := 0; i < b.N; i++ {
|
||||
uuid.New()
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("uuid.New-pooled", func(b *testing.B) {
|
||||
uuid.EnableRandPool()
|
||||
for i := 0; i < b.N; i++ {
|
||||
uuid.New()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParallel(b *testing.B) {
|
||||
b.Run("NewUUID", func(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
NewUUID()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("uuid.New-unpooled", func(b *testing.B) {
|
||||
uuid.DisableRandPool()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
uuid.New()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("uuid.New-pooled", func(b *testing.B) {
|
||||
uuid.EnableRandPool()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
uuid.New()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user