go_benchmark_test.go 3.27 KB
Newer Older
BSBandme's avatar
BSBandme committed
1 2 3
package main

import (
4 5 6 7 8 9
	benchmarkWrapper "../tmp"
	googleMessage1Proto2 "../tmp/datasets/google_message1/proto2"
	googleMessage1Proto3 "../tmp/datasets/google_message1/proto3"
	googleMessage2 "../tmp/datasets/google_message2"
	googleMessage3 "../tmp/datasets/google_message3"
	googleMessage4 "../tmp/datasets/google_message4"
BSBandme's avatar
BSBandme committed
10 11 12 13
	"flag"
	"github.com/golang/protobuf/proto"
	"io/ioutil"
	"testing"
BSBandme's avatar
BSBandme committed
14 15 16
)

// Data is returned by the Load function.
BSBandme's avatar
BSBandme committed
17 18 19 20
type Dataset struct {
	name        string
	newMessage  func() proto.Message
	marshaled   [][]byte
BSBandme's avatar
BSBandme committed
21
	unmarshaled []proto.Message
BSBandme's avatar
BSBandme committed
22 23
}

BSBandme's avatar
BSBandme committed
24
var datasets []Dataset
BSBandme's avatar
BSBandme committed
25 26

// This is used to getDefaultInstance for a message type.
BSBandme's avatar
BSBandme committed
27
func generateNewMessageFunction(dataset benchmarkWrapper.BenchmarkDataset) func() proto.Message {
BSBandme's avatar
BSBandme committed
28 29
	switch dataset.MessageName {
	case "benchmarks.proto3.GoogleMessage1":
BSBandme's avatar
BSBandme committed
30
		return func() proto.Message { return new(googleMessage1Proto3.GoogleMessage1) }
BSBandme's avatar
BSBandme committed
31
	case "benchmarks.proto2.GoogleMessage1":
BSBandme's avatar
BSBandme committed
32
		return func() proto.Message { return new(googleMessage1Proto2.GoogleMessage1) }
BSBandme's avatar
BSBandme committed
33
	case "benchmarks.proto2.GoogleMessage2":
BSBandme's avatar
BSBandme committed
34
		return func() proto.Message { return new(googleMessage2.GoogleMessage2) }
BSBandme's avatar
BSBandme committed
35
	case "benchmarks.google_message3.GoogleMessage3":
BSBandme's avatar
BSBandme committed
36
		return func() proto.Message { return new(googleMessage3.GoogleMessage3) }
BSBandme's avatar
BSBandme committed
37
	case "benchmarks.google_message4.GoogleMessage4":
BSBandme's avatar
BSBandme committed
38
		return func() proto.Message { return new(googleMessage4.GoogleMessage4) }
BSBandme's avatar
BSBandme committed
39
	default:
BSBandme's avatar
BSBandme committed
40
		panic("Unknown message type: " + dataset.MessageName)
BSBandme's avatar
BSBandme committed
41 42 43
	}
}

BSBandme's avatar
BSBandme committed
44
func init() {
BSBandme's avatar
BSBandme committed
45
	flag.Parse()
BSBandme's avatar
BSBandme committed
46 47 48 49 50
	for _, f := range flag.Args() {
		// Load the benchmark.
		b, err := ioutil.ReadFile(f)
		if err != nil {
			panic(err)
BSBandme's avatar
BSBandme committed
51 52
		}

BSBandme's avatar
BSBandme committed
53 54 55 56
		// Parse the benchmark.
		var dm benchmarkWrapper.BenchmarkDataset
		if err := proto.Unmarshal(b, &dm); err != nil {
			panic(err)
BSBandme's avatar
BSBandme committed
57 58
		}

BSBandme's avatar
BSBandme committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72
		// Determine the concrete protobuf message type to use.
		var ds Dataset
		ds.newMessage = generateNewMessageFunction(dm)

		// Unmarshal each test message.
		for _, payload := range dm.Payload {
			ds.marshaled = append(ds.marshaled, payload)
			m := ds.newMessage()
			if err := proto.Unmarshal(payload, m); err != nil {
				panic(err)
			}
			ds.unmarshaled = append(ds.unmarshaled, m)
		}
		ds.name = f
BSBandme's avatar
BSBandme committed
73

BSBandme's avatar
BSBandme committed
74
		datasets = append(datasets, ds)
BSBandme's avatar
BSBandme committed
75 76 77
	}
}

BSBandme's avatar
BSBandme committed
78 79 80 81 82
func Benchmark(b *testing.B) {
	for _, ds := range datasets {
		b.Run(ds.name, func(b *testing.B) {
			b.Run("Unmarshal", func(b *testing.B) {
				for i := 0; i < b.N; i++ {
83 84 85 86 87
					for j, payload := range ds.marshaled {
						out := ds.newMessage()
						if err := proto.Unmarshal(payload, out); err != nil {
							b.Fatalf("can't unmarshal message %d %v", j, err)
						}
BSBandme's avatar
BSBandme committed
88 89 90 91 92
					}
				}
			})
			b.Run("Marshal", func(b *testing.B) {
				for i := 0; i < b.N; i++ {
93 94 95 96
					for j, m := range ds.unmarshaled {
						if _, err := proto.Marshal(m); err != nil {
							b.Fatalf("can't marshal message %d %+v: %v", j, m, err)
						}
BSBandme's avatar
BSBandme committed
97 98 99 100 101
					}
				}
			})
			b.Run("Size", func(b *testing.B) {
				for i := 0; i < b.N; i++ {
102 103 104
					for _, m := range ds.unmarshaled {
						proto.Size(m)
					}
BSBandme's avatar
BSBandme committed
105 106 107 108
				}
			})
			b.Run("Clone", func(b *testing.B) {
				for i := 0; i < b.N; i++ {
109 110 111
					for _, m := range ds.unmarshaled {
						proto.Clone(m)
					}
BSBandme's avatar
BSBandme committed
112 113 114 115
				}
			})
			b.Run("Merge", func(b *testing.B) {
				for i := 0; i < b.N; i++ {
116 117 118 119
					for _, m := range ds.unmarshaled {
						out := ds.newMessage()
						proto.Merge(out, m)
					}
BSBandme's avatar
BSBandme committed
120 121 122
				}
			})
		})
BSBandme's avatar
BSBandme committed
123 124
	}
}