Skip to content

Commit b37ab01

Browse files
committed
cue: add large Value.MarshalJSON benchmark
Adapted from a smaller benchmark that Roger provided in https://cuelang.org/issue/2470 to also include nesting of structs as well as a long string, a long list, and a long struct. As can be seen by the current results, we allocate nearly 50MiB, which is very wasteful for the current benchmark size of 2000. cpu: AMD Ryzen 7 PRO 5850U with Radeon Graphics │ old │ │ sec/op │ LargeValueMarshalJSON-8 106.2m ± 1% │ old │ │ B/op │ LargeValueMarshalJSON-8 48.24Mi ± 8% │ old │ │ allocs/op │ LargeValueMarshalJSON-8 106.2k ± 2% For #2470. Signed-off-by: Daniel Martí <[email protected]> Change-Id: I437cc8fb644dd33dd0327860ca04ff66b7ab9275 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1201803 TryBot-Result: CUEcueckoo <[email protected]> Reviewed-by: Roger Peppe <[email protected]> Unity-Result: CUE porcuepine <[email protected]>
1 parent c8b32e9 commit b37ab01

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

cue/bench_test.go

+71
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515
package cue_test
1616

1717
import (
18+
"bytes"
19+
"fmt"
1820
"io/fs"
1921
"os"
2022
"path/filepath"
2123
"testing"
2224

25+
"cuelang.org/go/cue/cuecontext"
2326
"cuelang.org/go/internal/core/eval"
2427
"cuelang.org/go/internal/core/runtime"
2528
"cuelang.org/go/internal/cuetdtest"
@@ -107,3 +110,71 @@ func Benchmark(b *testing.B) {
107110
b.Fatal(err)
108111
}
109112
}
113+
114+
// TODO(mvdan): move this benchmark to internal/encoding
115+
// and cover other encodings too.
116+
// We should also cover both encoding and decoding performance.
117+
func BenchmarkLargeValueMarshalJSON(b *testing.B) {
118+
b.ReportAllocs()
119+
size := 2000
120+
121+
var buf bytes.Buffer
122+
123+
fmt.Fprintf(&buf, "longString: \"")
124+
for range size {
125+
fmt.Fprintf(&buf, "x")
126+
}
127+
fmt.Fprintf(&buf, "\"\n")
128+
129+
fmt.Fprintf(&buf, "nestedList: ")
130+
for range size {
131+
fmt.Fprintf(&buf, "[")
132+
}
133+
fmt.Fprintf(&buf, "0")
134+
for range size {
135+
fmt.Fprintf(&buf, "]")
136+
}
137+
fmt.Fprintf(&buf, "\n")
138+
139+
fmt.Fprintf(&buf, "longList: [")
140+
for i := range size {
141+
if i > 0 {
142+
fmt.Fprintf(&buf, ",")
143+
}
144+
fmt.Fprintf(&buf, "0")
145+
}
146+
fmt.Fprintf(&buf, "]\n")
147+
148+
fmt.Fprintf(&buf, "nestedStruct: ")
149+
for range size {
150+
fmt.Fprintf(&buf, "{k:")
151+
}
152+
fmt.Fprintf(&buf, "0")
153+
for range size {
154+
fmt.Fprintf(&buf, "}")
155+
}
156+
fmt.Fprintf(&buf, "\n")
157+
158+
fmt.Fprintf(&buf, "longStruct: {")
159+
for i := range size {
160+
if i > 0 {
161+
fmt.Fprintf(&buf, ",")
162+
}
163+
fmt.Fprintf(&buf, "k%d: 0", i)
164+
}
165+
fmt.Fprintf(&buf, "}\n")
166+
167+
ctx := cuecontext.New()
168+
val := ctx.CompileBytes(buf.Bytes())
169+
if err := val.Err(); err != nil {
170+
b.Fatal(err)
171+
}
172+
b.ResetTimer()
173+
for i := 0; i < b.N; i++ {
174+
data, err := val.MarshalJSON()
175+
if err != nil {
176+
b.Fatal(err)
177+
}
178+
_ = data
179+
}
180+
}

0 commit comments

Comments
 (0)