Skip to content

Commit 934d63d

Browse files
authored
Use base64.Encode instead of EncodeToString in JWS marshal (#1565)
* Use base64.Encode instead of EncodeToString in JWS marshal Write []byte directly to buffer instead of converting to string. MarshalFlattened: -20% mem (875→699 B/op), -17% allocs (12→10) MarshalFull: -14% mem (1913→1639 B/op), -11% allocs (27→24) * Fix benchmark lint: use b.Loop()
1 parent 0c09d87 commit 934d63d

File tree

2 files changed

+81
-6
lines changed

2 files changed

+81
-6
lines changed

jws/bench_marshal_test.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package jws_test
2+
3+
import (
4+
"crypto/ecdsa"
5+
"crypto/elliptic"
6+
"crypto/rand"
7+
"testing"
8+
9+
"github.com/lestrrat-go/jwx/v3/jwa"
10+
"github.com/lestrrat-go/jwx/v3/jws"
11+
)
12+
13+
func BenchmarkMarshalFlattened(b *testing.B) {
14+
b.ReportAllocs()
15+
16+
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
17+
if err != nil {
18+
b.Fatal(err)
19+
}
20+
21+
payload := []byte(`{"iss":"bench","sub":"test","aud":"perf","exp":9999999999}`)
22+
signed, err := jws.Sign(payload, jws.WithKey(jwa.ES256(), key))
23+
if err != nil {
24+
b.Fatal(err)
25+
}
26+
27+
msg, err := jws.Parse(signed)
28+
if err != nil {
29+
b.Fatal(err)
30+
}
31+
32+
b.ResetTimer()
33+
for b.Loop() {
34+
_, err := msg.MarshalJSON()
35+
if err != nil {
36+
b.Fatal(err)
37+
}
38+
}
39+
}
40+
41+
func BenchmarkMarshalFull(b *testing.B) {
42+
b.ReportAllocs()
43+
44+
key1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
45+
if err != nil {
46+
b.Fatal(err)
47+
}
48+
key2, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
49+
if err != nil {
50+
b.Fatal(err)
51+
}
52+
53+
payload := []byte(`{"iss":"bench","sub":"test","aud":"perf","exp":9999999999}`)
54+
signed, err := jws.Sign(payload,
55+
jws.WithJSON(),
56+
jws.WithKey(jwa.ES256(), key1),
57+
jws.WithKey(jwa.ES256(), key2),
58+
)
59+
if err != nil {
60+
b.Fatal(err)
61+
}
62+
63+
msg, err := jws.Parse(signed)
64+
if err != nil {
65+
b.Fatal(err)
66+
}
67+
68+
b.ResetTimer()
69+
for b.Loop() {
70+
_, err := msg.MarshalJSON()
71+
if err != nil {
72+
b.Fatal(err)
73+
}
74+
}
75+
}

jws/message.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ func (m Message) marshalFlattened() ([]byte, error) {
408408
buf.WriteRune(tokens.Comma)
409409
}
410410
buf.WriteString(`"payload":"`)
411-
buf.WriteString(base64.EncodeToString(m.payload))
411+
buf.Write(base64.Encode(m.payload))
412412
buf.WriteRune('"')
413413

414414
if protected := sig.protected; protected != nil {
@@ -417,12 +417,12 @@ func (m Message) marshalFlattened() ([]byte, error) {
417417
return nil, fmt.Errorf(`failed to marshal "protected" (flattened format): %w`, err)
418418
}
419419
buf.WriteString(`,"protected":"`)
420-
buf.WriteString(base64.EncodeToString(protectedbuf))
420+
buf.Write(base64.Encode(protectedbuf))
421421
buf.WriteRune('"')
422422
}
423423

424424
buf.WriteString(`,"signature":"`)
425-
buf.WriteString(base64.EncodeToString(sig.signature))
425+
buf.Write(base64.Encode(sig.signature))
426426
buf.WriteRune('"')
427427
buf.WriteRune(tokens.CloseCurlyBracket)
428428

@@ -435,7 +435,7 @@ func (m Message) marshalFull() ([]byte, error) {
435435
defer pool.BytesBuffer().Put(buf)
436436

437437
buf.WriteString(`{"payload":"`)
438-
buf.WriteString(base64.EncodeToString(m.payload))
438+
buf.Write(base64.Encode(m.payload))
439439
buf.WriteString(`","signatures":[`)
440440
for i, sig := range m.signatures {
441441
if i > 0 {
@@ -463,7 +463,7 @@ func (m Message) marshalFull() ([]byte, error) {
463463
buf.WriteRune(tokens.Comma)
464464
}
465465
buf.WriteString(`"protected":"`)
466-
buf.WriteString(base64.EncodeToString(protectedbuf))
466+
buf.Write(base64.Encode(protectedbuf))
467467
buf.WriteRune('"')
468468
wrote = true
469469
}
@@ -474,7 +474,7 @@ func (m Message) marshalFull() ([]byte, error) {
474474
buf.WriteRune(tokens.Comma)
475475
}
476476
buf.WriteString(`"signature":"`)
477-
buf.WriteString(base64.EncodeToString(sig.signature))
477+
buf.Write(base64.Encode(sig.signature))
478478
buf.WriteString(`"`)
479479
}
480480
buf.WriteString(`}`)

0 commit comments

Comments
 (0)