Skip to content

Commit

Permalink
cue: add large Value.MarshalJSON benchmark
Browse files Browse the repository at this point in the history
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í <mvdan@mvdan.cc>
Change-Id: I437cc8fb644dd33dd0327860ca04ff66b7ab9275
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1201803
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
  • Loading branch information
mvdan committed Sep 25, 2024
1 parent c8b32e9 commit b37ab01
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions cue/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
package cue_test

import (
"bytes"
"fmt"
"io/fs"
"os"
"path/filepath"
"testing"

"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/internal/core/eval"
"cuelang.org/go/internal/core/runtime"
"cuelang.org/go/internal/cuetdtest"
Expand Down Expand Up @@ -107,3 +110,71 @@ func Benchmark(b *testing.B) {
b.Fatal(err)
}
}

// TODO(mvdan): move this benchmark to internal/encoding
// and cover other encodings too.
// We should also cover both encoding and decoding performance.
func BenchmarkLargeValueMarshalJSON(b *testing.B) {
b.ReportAllocs()
size := 2000

var buf bytes.Buffer

fmt.Fprintf(&buf, "longString: \"")
for range size {
fmt.Fprintf(&buf, "x")
}
fmt.Fprintf(&buf, "\"\n")

fmt.Fprintf(&buf, "nestedList: ")
for range size {
fmt.Fprintf(&buf, "[")
}
fmt.Fprintf(&buf, "0")
for range size {
fmt.Fprintf(&buf, "]")
}
fmt.Fprintf(&buf, "\n")

fmt.Fprintf(&buf, "longList: [")
for i := range size {
if i > 0 {
fmt.Fprintf(&buf, ",")
}
fmt.Fprintf(&buf, "0")
}
fmt.Fprintf(&buf, "]\n")

fmt.Fprintf(&buf, "nestedStruct: ")
for range size {
fmt.Fprintf(&buf, "{k:")
}
fmt.Fprintf(&buf, "0")
for range size {
fmt.Fprintf(&buf, "}")
}
fmt.Fprintf(&buf, "\n")

fmt.Fprintf(&buf, "longStruct: {")
for i := range size {
if i > 0 {
fmt.Fprintf(&buf, ",")
}
fmt.Fprintf(&buf, "k%d: 0", i)
}
fmt.Fprintf(&buf, "}\n")

ctx := cuecontext.New()
val := ctx.CompileBytes(buf.Bytes())
if err := val.Err(); err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
data, err := val.MarshalJSON()
if err != nil {
b.Fatal(err)
}
_ = data
}
}

0 comments on commit b37ab01

Please sign in to comment.