cuelang.org/go@v0.13.0/cue/bench_test.go (about) 1 // Copyright 2020 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cue_test 16 17 import ( 18 "bytes" 19 "fmt" 20 "io/fs" 21 "os" 22 "path/filepath" 23 "testing" 24 25 "cuelang.org/go/cue/cuecontext" 26 "cuelang.org/go/internal/core/eval" 27 "cuelang.org/go/internal/core/runtime" 28 "cuelang.org/go/internal/cuetdtest" 29 "cuelang.org/go/internal/cuetest" 30 "cuelang.org/go/internal/cuetxtar" 31 "golang.org/x/tools/txtar" 32 ) 33 34 var ( 35 matrix = cuetdtest.FullMatrix 36 ) 37 38 func Benchmark(b *testing.B) { 39 root := "testdata/benchmarks" 40 err := filepath.WalkDir(root, func(fullpath string, entry fs.DirEntry, err error) error { 41 if err != nil { 42 return err 43 } 44 45 if entry.IsDir() || filepath.Ext(fullpath) != ".txtar" { 46 return nil 47 } 48 49 a, err := txtar.ParseFile(fullpath) 50 if err != nil { 51 return err 52 } 53 54 inst := cuetxtar.Load(a, b.TempDir())[0] 55 if inst.Err != nil { 56 return inst.Err 57 } 58 59 r := runtime.New() 60 v, err := r.Build(nil, inst) 61 if err != nil { 62 b.Fatal(err) 63 } 64 e := eval.New(r) 65 ctx := e.NewContext(v) 66 v.Finalize(ctx) 67 68 if cuetest.UpdateGoldenFiles { 69 const statsFile = "stats.txt" 70 var stats txtar.File 71 var statsPos int 72 for i, f := range a.Files { 73 if f.Name == statsFile { 74 stats = f 75 statsPos = i 76 break 77 } 78 } 79 if stats.Name == "" { 80 // At stats.txt as the first file. 81 a.Files = append([]txtar.File{{ 82 Name: statsFile, 83 }}, a.Files...) 84 } 85 86 a.Files[statsPos].Data = []byte(ctx.Stats().String() + "\n\n") 87 88 info, err := entry.Info() 89 if err != nil { 90 b.Fatal(err) 91 } 92 os.WriteFile(fullpath, txtar.Format(a), info.Mode()) 93 } 94 95 b.Run(entry.Name(), func(b *testing.B) { 96 for _, m := range matrix { 97 b.Run(m.Name(), func(b *testing.B) { 98 b.ReportAllocs() 99 for i := 0; i < b.N; i++ { 100 ctx := m.CueContext() 101 value := ctx.BuildInstance(cuetxtar.Load(a, b.TempDir())[0]) 102 value.Validate() 103 } 104 }) 105 } 106 }) 107 return nil 108 }) 109 if err != nil { 110 b.Fatal(err) 111 } 112 } 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 }