github.com/k14s/starlark-go@v0.0.0-20200720175618-3a5c849cc368/starlark/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 starlark_test
     6  
     7  import (
     8  	"bytes"
     9  	"io/ioutil"
    10  	"path/filepath"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/k14s/starlark-go/starlark"
    15  	"github.com/k14s/starlark-go/starlarktest"
    16  )
    17  
    18  func Benchmark(b *testing.B) {
    19  	defer setOptions("")
    20  
    21  	testdata := starlarktest.DataFile("starlark", ".")
    22  	thread := new(starlark.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 := starlark.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.(*starlark.Function); ok && strings.HasPrefix(name, "bench_") {
    47  				b.Run(name, func(b *testing.B) {
    48  					for i := 0; i < b.N; i++ {
    49  						_, err := starlark.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 := starlarktest.DataFile("starlark", "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 *starlark.Program
    78  	b.Run("compile", func(b *testing.B) {
    79  		for i := 0; i < b.N; i++ {
    80  			var err error
    81  			_, prog, err = starlark.SourceProgram(filename, src, starlark.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 := starlark.CompiledProgram(in); err != nil {
   106  				b.Fatal(err)
   107  			}
   108  		}
   109  	})
   110  }