Skip to content

Commit b4a958c

Browse files
authored
Eliminate redundant lock acquisitions in LookupKeyID (#1563)
* Eliminate redundant lock acquisitions in LookupKeyID Iterate s.keys directly under outer RLock instead of calling s.Len() and s.Key() which each reacquire the lock. ~2x faster across all set sizes: size=1: 13.3→6.0 ns/op size=10: 40→21 ns/op (mid), 62→32 ns/op (end) size=100: 289→149 ns/op (mid), 566→291 ns/op (end) * Fix benchmark lint: use fmt.Appendf
1 parent e9db830 commit b4a958c

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

jwk/bench_set_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package jwk_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/lestrrat-go/jwx/v3/jwk"
8+
)
9+
10+
func makeKeySet(b *testing.B, n int) jwk.Set {
11+
b.Helper()
12+
set := jwk.NewSet()
13+
for i := range n {
14+
key, err := jwk.Import(fmt.Appendf(nil, "secret-key-value-%04d", i))
15+
if err != nil {
16+
b.Fatalf("failed to create key: %v", err)
17+
}
18+
if err := key.Set(jwk.KeyIDKey, fmt.Sprintf("kid-%04d", i)); err != nil {
19+
b.Fatalf("failed to set key id: %v", err)
20+
}
21+
if err := set.AddKey(key); err != nil {
22+
b.Fatalf("failed to add key: %v", err)
23+
}
24+
}
25+
return set
26+
}
27+
28+
func BenchmarkLookupKeyID(b *testing.B) {
29+
for _, size := range []int{1, 10, 100} {
30+
set := makeKeySet(b, size)
31+
32+
midKID := fmt.Sprintf("kid-%04d", size/2)
33+
b.Run(fmt.Sprintf("size=%d/mid", size), func(b *testing.B) {
34+
b.ReportAllocs()
35+
for range b.N {
36+
key, ok := set.LookupKeyID(midKID)
37+
if !ok || key == nil {
38+
b.Fatal("key not found")
39+
}
40+
}
41+
})
42+
43+
endKID := fmt.Sprintf("kid-%04d", size-1)
44+
b.Run(fmt.Sprintf("size=%d/end", size), func(b *testing.B) {
45+
b.ReportAllocs()
46+
for range b.N {
47+
key, ok := set.LookupKeyID(endKID)
48+
if !ok || key == nil {
49+
b.Fatal("key not found")
50+
}
51+
}
52+
})
53+
}
54+
}

jwk/set.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,7 @@ func (s *set) LookupKeyID(kid string) (Key, bool) {
280280
s.mu.RLock()
281281
defer s.mu.RUnlock()
282282

283-
for i := range s.Len() {
284-
key, ok := s.Key(i)
285-
if !ok {
286-
return nil, false
287-
}
283+
for _, key := range s.keys {
288284
gotkid, ok := key.KeyID()
289285
if ok && gotkid == kid {
290286
return key, true

0 commit comments

Comments
 (0)