github.com/lab47/exprcore@v0.0.0-20210525052339-fb7d6bd9331e/exprcore/bench_test.go (about) 1 // Copyright 2018 The Bazel Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package exprcore_test 6 7 import ( 8 "bytes" 9 "io/ioutil" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 "github.com/lab47/exprcore/exprcore" 15 "github.com/lab47/exprcore/exprcoretest" 16 ) 17 18 func Benchmark(b *testing.B) { 19 defer setOptions("") 20 21 testdata := exprcoretest.DataFile("exprcore", ".") 22 thread := new(exprcore.Thread) 23 for _, file := range []string{ 24 "testdata/benchmark.star", 25 // ... 26 } { 27 28 filename := filepath.Join(testdata, file) 29 30 src, err := ioutil.ReadFile(filename) 31 if err != nil { 32 b.Error(err) 33 continue 34 } 35 setOptions(string(src)) 36 37 // Evaluate the file once. 38 globals, err := exprcore.ExecFile(thread, filename, src, nil) 39 if err != nil { 40 reportEvalError(b, err) 41 } 42 43 // Repeatedly call each global function named bench_* as a benchmark. 44 for _, name := range globals.Keys() { 45 value := globals[name] 46 if fn, ok := value.(*exprcore.Function); ok && strings.HasPrefix(name, "bench_") { 47 b.Run(name, func(b *testing.B) { 48 for i := 0; i < b.N; i++ { 49 _, err := exprcore.Call(thread, fn, nil, nil) 50 if err != nil { 51 reportEvalError(b, err) 52 } 53 } 54 }) 55 } 56 } 57 } 58 } 59 60 // BenchmarkProgram measures operations relevant to compiled programs. 61 // TODO(adonovan): use a bigger testdata program. 62 func BenchmarkProgram(b *testing.B) { 63 // Measure time to read a source file (approx 600us but depends on hardware and file system). 64 filename := exprcoretest.DataFile("exprcore", "testdata/paths.star") 65 var src []byte 66 b.Run("read", func(b *testing.B) { 67 for i := 0; i < b.N; i++ { 68 var err error 69 src, err = ioutil.ReadFile(filename) 70 if err != nil { 71 b.Fatal(err) 72 } 73 } 74 }) 75 76 // Measure time to turn a source filename into a compiled program (approx 450us). 77 var prog *exprcore.Program 78 b.Run("compile", func(b *testing.B) { 79 for i := 0; i < b.N; i++ { 80 var err error 81 _, prog, err = exprcore.SourceProgram(filename, src, exprcore.StringDict(nil).Has) 82 if err != nil { 83 b.Fatal(err) 84 } 85 } 86 }) 87 88 // Measure time to encode a compiled program to a memory buffer 89 // (approx 20us; was 75-120us with gob encoding). 90 var out bytes.Buffer 91 b.Run("encode", func(b *testing.B) { 92 for i := 0; i < b.N; i++ { 93 out.Reset() 94 if err := prog.Write(&out); err != nil { 95 b.Fatal(err) 96 } 97 } 98 }) 99 100 // Measure time to decode a compiled program from a memory buffer 101 // (approx 20us; was 135-250us with gob encoding) 102 b.Run("decode", func(b *testing.B) { 103 for i := 0; i < b.N; i++ { 104 in := bytes.NewReader(out.Bytes()) 105 if _, err := exprcore.CompiledProgram(in); err != nil { 106 b.Fatal(err) 107 } 108 } 109 }) 110 }