| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| //go:build !build_with_native_toolchain |
| // +build !build_with_native_toolchain |
| |
| package main |
| |
| import ( |
| "bytes" |
| "fmt" |
| "io/ioutil" |
| "log" |
| "os" |
| "strings" |
| "text/template" |
| ) |
| |
| var fileTmpl = template.Must(template.New("fileTmpl").Parse( |
| `// Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Generated. To regenerate, run: |
| // $FUCHSIA_DIR/src/tests/benchmarks/fidl/fidlc/regen.sh |
| |
| struct Benchmark { |
| const char* name; |
| const char* fidl; |
| }; |
| |
| constexpr Benchmark benchmarks[] = { |
| {{- range .Benchmarks }} |
| Benchmark{ |
| .name = "{{ .Name }}", |
| .fidl = R"FIDL( |
| {{ .FIDL }} |
| )FIDL", |
| }, |
| {{- end }} |
| }; |
| `)) |
| |
| // file is the input to the file template. |
| type file struct { |
| Benchmarks []fileBenchmark |
| } |
| |
| // fileBenchmark is a benchmark in the file template. |
| type fileBenchmark struct { |
| Name string |
| FIDL string |
| } |
| |
| // benchmarkTemplate is a template for a particular kind of benchmark. |
| // |
| // FIDLTemplate is provided a slice of elements with needed template fields |
| // e.g. I and IPlusOne |
| type benchmarkTemplate struct { |
| Name string |
| FIDLTemplate *template.Template |
| } |
| |
| // benchmark is an instance of a benchmarkTemplate. |
| type benchmark struct { |
| Template benchmarkTemplate |
| Size int |
| } |
| |
| var structFieldBenchmarkTemplate = benchmarkTemplate{ |
| Name: "StructField", |
| FIDLTemplate: template.Must(template.New("structFieldTmpl").Parse(` |
| library example; |
| |
| type TestStruct = struct { |
| {{ range . -}} |
| f{{ .IPlusOne }} int8; |
| {{ end -}} |
| };`)), |
| } |
| |
| var structDeepBenchmarkTemplate = benchmarkTemplate{ |
| Name: "StructDeep", |
| FIDLTemplate: template.Must(template.New("structDeepTmpl").Parse(` |
| library example; |
| |
| type TestStruct0 = struct { |
| val int8; |
| }; |
| {{ range . }} |
| type TestStruct{{ .IPlusOne }} = struct { |
| val TestStruct{{ .I }}; |
| }; |
| {{ end -}} |
| `)), |
| } |
| |
| var tableFieldBenchmarkTemplate = benchmarkTemplate{ |
| Name: "TableField", |
| FIDLTemplate: template.Must(template.New("tableFieldTmpl").Parse(` |
| library example; |
| |
| type TestTable = table { |
| {{ range . -}} |
| {{ .IPlusOne }}: f{{ .IPlusOne }} int8; |
| {{ end -}} |
| };`)), |
| } |
| |
| var tableDeepBenchmarkTemplate = benchmarkTemplate{ |
| Name: "TableDeep", |
| FIDLTemplate: template.Must(template.New("tableDeepTmpl").Parse(` |
| library example; |
| |
| type TestTable0 = table { |
| 1: val int8; |
| }; |
| {{ range . }} |
| type TestTable{{ .IPlusOne }} = table { |
| 1: val TestTable{{ .I }}; |
| }; |
| {{ end -}} |
| `)), |
| } |
| |
| var unionFieldBenchmarkTemplate = benchmarkTemplate{ |
| Name: "UnionField", |
| FIDLTemplate: template.Must(template.New("unionFieldTmpl").Parse(` |
| library example; |
| |
| type TestUnion = union { |
| {{ range . -}} |
| {{ .IPlusOne }}: f{{ .IPlusOne }} int8; |
| {{ end -}} |
| };`)), |
| } |
| |
| var unionDeepBenchmarkTemplate = benchmarkTemplate{ |
| Name: "UnionDeep", |
| FIDLTemplate: template.Must(template.New("unionDeepTmpl").Parse(` |
| library example; |
| |
| type TestUnion0 = union { |
| 1: val int8; |
| }; |
| {{ range . }} |
| type TestUnion{{ .IPlusOne }} = union { |
| 1: val TestUnion{{ .I }}; |
| }; |
| {{ end -}} |
| `)), |
| } |
| |
| var benchmarks = []benchmark{ |
| { |
| Template: structFieldBenchmarkTemplate, |
| Size: 64, |
| }, |
| // NOTE: it would be preferable to test larger sizes for StructDeep |
| // because it can have poor scaling, but unfortunately larger sizes |
| // are too slow to build now. Consider increasing the size when |
| // build performance improves. |
| { |
| Template: structDeepBenchmarkTemplate, |
| Size: 8, |
| }, |
| { |
| Template: tableFieldBenchmarkTemplate, |
| Size: 63, |
| }, |
| { |
| Template: tableDeepBenchmarkTemplate, |
| Size: 63, |
| }, |
| { |
| Template: unionFieldBenchmarkTemplate, |
| Size: 64, |
| }, |
| { |
| Template: unionDeepBenchmarkTemplate, |
| Size: 64, |
| }, |
| } |
| |
| func main() { |
| var file file |
| for _, b := range benchmarks { |
| fb, err := processBenchmark(b) |
| if err != nil { |
| log.Fatal(err) |
| } |
| file.Benchmarks = append(file.Benchmarks, fb) |
| } |
| |
| var buffer bytes.Buffer |
| if err := fileTmpl.Execute(&buffer, file); err != nil { |
| log.Fatal(err) |
| } |
| |
| outputFile := os.Args[1] |
| if err := ioutil.WriteFile(outputFile, buffer.Bytes(), 0644); err != nil { |
| log.Fatal(err) |
| } |
| } |
| |
| func processBenchmark(b benchmark) (fileBenchmark, error) { |
| type benchmarkTmpl struct { |
| I int |
| IPlusOne int |
| } |
| input := make([]benchmarkTmpl, b.Size) |
| for i := range input { |
| input[i] = benchmarkTmpl{ |
| I: i, |
| IPlusOne: i + 1, |
| } |
| } |
| var sb strings.Builder |
| if err := b.Template.FIDLTemplate.Execute(&sb, input); err != nil { |
| return fileBenchmark{}, err |
| } |
| |
| return fileBenchmark{ |
| Name: fmt.Sprintf("%s/%d", b.Template.Name, b.Size), |
| FIDL: sb.String(), |
| }, nil |
| } |