Rewrite go_benchmark

pull/4361/head
BSBandme 7 years ago
parent 6d2c6a0099
commit 501c13f65a
  1. 5
      benchmarks/Makefile.am
  2. 172
      benchmarks/go_benchmark_test.go

@ -288,10 +288,7 @@ go-benchmark: go_protoc_middleman go_protoc_middleman2
@echo "Writing shortcut script go-benchmark..." @echo "Writing shortcut script go-benchmark..."
@echo '#! /bin/sh' > go-benchmark @echo '#! /bin/sh' > go-benchmark
@echo 'mkdir tmp_cc && mv *.cc tmp_cc' >> go-benchmark @echo 'mkdir tmp_cc && mv *.cc tmp_cc' >> go-benchmark
@echo 'for file in $$@; do' >> go-benchmark @echo 'go test -bench=. -- $$@' >> go-benchmark
@echo ' echo "Testing go benchmark for data file: $$file";' >> go-benchmark
@echo ' go test -bench=. -- $$file;' >> go-benchmark
@echo 'done' >> go-benchmark
@echo 'mv tmp_cc/* . && rm -rf tmp_cc' >> go-benchmark @echo 'mv tmp_cc/* . && rm -rf tmp_cc' >> go-benchmark
@chmod +x go-benchmark @chmod +x go-benchmark

@ -7,127 +7,117 @@ import (
googleMessage2 "./tmp/datasets/google_message2" googleMessage2 "./tmp/datasets/google_message2"
googleMessage3 "./tmp/datasets/google_message3" googleMessage3 "./tmp/datasets/google_message3"
googleMessage4 "./tmp/datasets/google_message4" googleMessage4 "./tmp/datasets/google_message4"
"errors"
"flag" "flag"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"io/ioutil" "io/ioutil"
"os"
"testing" "testing"
) )
// Data is returned by the Load function. // Data is returned by the Load function.
type Data struct { type Dataset struct {
// marshaled is a slice of marshaled protocol name string
// buffers. 1:1 with unmarshaled. newMessage func() proto.Message
marshaled [][]byte marshaled [][]byte
// Unmarshaled is a slice of unmarshaled protocol
// buffers. 1:1 with marshaled.
unmarshaled []proto.Message unmarshaled []proto.Message
count int
} }
var data *Data var datasets []Dataset
var counter int
type GetDefaultInstanceFunction func() proto.Message
var getDefaultInstance GetDefaultInstanceFunction
// This is used to getDefaultInstance for a message type. // This is used to getDefaultInstance for a message type.
func generateGetDefaltInstanceFunction(dataset benchmarkWrapper.BenchmarkDataset) error { func generateNewMessageFunction(dataset benchmarkWrapper.BenchmarkDataset) func() proto.Message {
switch dataset.MessageName { switch dataset.MessageName {
case "benchmarks.proto3.GoogleMessage1": case "benchmarks.proto3.GoogleMessage1":
getDefaultInstance = func() proto.Message { return &googleMessage1Proto3.GoogleMessage1{} } return func() proto.Message { return new(googleMessage1Proto3.GoogleMessage1) }
return nil
case "benchmarks.proto2.GoogleMessage1": case "benchmarks.proto2.GoogleMessage1":
getDefaultInstance = func() proto.Message { return &googleMessage1Proto2.GoogleMessage1{} } return func() proto.Message { return new(googleMessage1Proto2.GoogleMessage1) }
return nil
case "benchmarks.proto2.GoogleMessage2": case "benchmarks.proto2.GoogleMessage2":
getDefaultInstance = func() proto.Message { return &googleMessage2.GoogleMessage2{} } return func() proto.Message { return new(googleMessage2.GoogleMessage2) }
return nil
case "benchmarks.google_message3.GoogleMessage3": case "benchmarks.google_message3.GoogleMessage3":
getDefaultInstance = func() proto.Message { return &googleMessage3.GoogleMessage3{} } return func() proto.Message { return new(googleMessage3.GoogleMessage3) }
return nil
case "benchmarks.google_message4.GoogleMessage4": case "benchmarks.google_message4.GoogleMessage4":
getDefaultInstance = func() proto.Message { return &googleMessage4.GoogleMessage4{} } return func() proto.Message { return new(googleMessage4.GoogleMessage4) }
return nil
default: default:
return errors.New("Unknown message type: " + dataset.MessageName) panic("Unknown message type: " + dataset.MessageName)
} }
} }
func TestMain(m *testing.M) { func init() {
flag.Parse() flag.Parse()
data = new(Data) for _, f := range flag.Args() {
rawData, err := ioutil.ReadFile(flag.Arg(0)) // Load the benchmark.
if err != nil { b, err := ioutil.ReadFile(f)
panic("Couldn't find file" + flag.Arg(0)) if err != nil {
} panic(err)
var dataset benchmarkWrapper.BenchmarkDataset
if err = proto.Unmarshal(rawData, &dataset); err != nil {
panic("The raw input data can't be parse into BenchmarkDataset message.")
}
generateGetDefaltInstanceFunction(dataset)
for _, payload := range dataset.Payload {
data.marshaled = append(data.marshaled, payload)
m := getDefaultInstance()
proto.Unmarshal(payload, m)
data.unmarshaled = append(data.unmarshaled, m)
}
data.count = len(data.unmarshaled)
os.Exit(m.Run())
}
func BenchmarkUnmarshal(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
payload := data.marshaled[counter%data.count]
out := getDefaultInstance()
if err := proto.Unmarshal(payload, out); err != nil {
b.Fatalf("can't unmarshal message %d %v", counter%data.count, err)
} }
counter++
}
}
func BenchmarkMarshal(b *testing.B) { // Parse the benchmark.
b.ReportAllocs() var dm benchmarkWrapper.BenchmarkDataset
for i := 0; i < b.N; i++ { if err := proto.Unmarshal(b, &dm); err != nil {
m := data.unmarshaled[counter%data.count] panic(err)
if _, err := proto.Marshal(m); err != nil {
b.Fatalf("can't marshal message %d %+v: %v", counter%data.count, m, err)
} }
counter++
}
}
func BenchmarkSize(b *testing.B) { // Determine the concrete protobuf message type to use.
b.ReportAllocs() var ds Dataset
for i := 0; i < b.N; i++ { ds.newMessage = generateNewMessageFunction(dm)
proto.Size(data.unmarshaled[counter%data.count])
counter++ // 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
func BenchmarkClone(b *testing.B) { datasets = append(datasets, ds)
b.ReportAllocs()
for i := 0; i < b.N; i++ {
proto.Clone(data.unmarshaled[counter%data.count])
counter++
} }
} }
func BenchmarkMerge(b *testing.B) { func Benchmark(b *testing.B) {
b.ReportAllocs() for _, ds := range datasets {
for i := 0; i < b.N; i++ { b.Run(ds.name, func(b *testing.B) {
out := getDefaultInstance() counter := 0
proto.Merge(out, data.unmarshaled[counter%data.count]) count := len(ds.marshaled)
counter++ b.Run("Unmarshal", func(b *testing.B) {
for i := 0; i < b.N; i++ {
payload := ds.marshaled[counter%count]
out := ds.newMessage()
if err := proto.Unmarshal(payload, out); err != nil {
b.Fatalf("can't unmarshal message %d %v", counter%count, err)
}
counter++
}
})
b.Run("Marshal", func(b *testing.B) {
for i := 0; i < b.N; i++ {
m := ds.unmarshaled[counter%count]
if _, err := proto.Marshal(m); err != nil {
b.Fatalf("can't marshal message %d %+v: %v", counter%count, m, err)
}
counter++
}
})
b.Run("Size", func(b *testing.B) {
for i := 0; i < b.N; i++ {
proto.Size(ds.unmarshaled[counter%count])
counter++
}
})
b.Run("Clone", func(b *testing.B) {
for i := 0; i < b.N; i++ {
proto.Clone(ds.unmarshaled[counter%count])
counter++
}
})
b.Run("Merge", func(b *testing.B) {
for i := 0; i < b.N; i++ {
out := ds.newMessage()
proto.Merge(out, ds.unmarshaled[counter%count])
counter++
}
})
})
} }
} }

Loading…
Cancel
Save