1*1b3f573fSAndroid Build Coastguard Workerpackage main 2*1b3f573fSAndroid Build Coastguard Worker 3*1b3f573fSAndroid Build Coastguard Workerimport ( 4*1b3f573fSAndroid Build Coastguard Worker benchmarkWrapper "../tmp" 5*1b3f573fSAndroid Build Coastguard Worker googleMessage1Proto2 "../tmp/datasets/google_message1/proto2" 6*1b3f573fSAndroid Build Coastguard Worker googleMessage1Proto3 "../tmp/datasets/google_message1/proto3" 7*1b3f573fSAndroid Build Coastguard Worker googleMessage2 "../tmp/datasets/google_message2" 8*1b3f573fSAndroid Build Coastguard Worker googleMessage3 "../tmp/datasets/google_message3" 9*1b3f573fSAndroid Build Coastguard Worker googleMessage4 "../tmp/datasets/google_message4" 10*1b3f573fSAndroid Build Coastguard Worker "flag" 11*1b3f573fSAndroid Build Coastguard Worker "github.com/golang/protobuf/proto" 12*1b3f573fSAndroid Build Coastguard Worker "io/ioutil" 13*1b3f573fSAndroid Build Coastguard Worker "testing" 14*1b3f573fSAndroid Build Coastguard Worker) 15*1b3f573fSAndroid Build Coastguard Worker 16*1b3f573fSAndroid Build Coastguard Worker// Data is returned by the Load function. 17*1b3f573fSAndroid Build Coastguard Workertype Dataset struct { 18*1b3f573fSAndroid Build Coastguard Worker name string 19*1b3f573fSAndroid Build Coastguard Worker newMessage func() proto.Message 20*1b3f573fSAndroid Build Coastguard Worker marshaled [][]byte 21*1b3f573fSAndroid Build Coastguard Worker unmarshaled []proto.Message 22*1b3f573fSAndroid Build Coastguard Worker} 23*1b3f573fSAndroid Build Coastguard Worker 24*1b3f573fSAndroid Build Coastguard Workervar datasets []Dataset 25*1b3f573fSAndroid Build Coastguard Worker 26*1b3f573fSAndroid Build Coastguard Worker// This is used to getDefaultInstance for a message type. 27*1b3f573fSAndroid Build Coastguard Workerfunc generateNewMessageFunction(dataset benchmarkWrapper.BenchmarkDataset) func() proto.Message { 28*1b3f573fSAndroid Build Coastguard Worker switch dataset.MessageName { 29*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.proto3.GoogleMessage1": 30*1b3f573fSAndroid Build Coastguard Worker return func() proto.Message { return new(googleMessage1Proto3.GoogleMessage1) } 31*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.proto2.GoogleMessage1": 32*1b3f573fSAndroid Build Coastguard Worker return func() proto.Message { return new(googleMessage1Proto2.GoogleMessage1) } 33*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.proto2.GoogleMessage2": 34*1b3f573fSAndroid Build Coastguard Worker return func() proto.Message { return new(googleMessage2.GoogleMessage2) } 35*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.google_message3.GoogleMessage3": 36*1b3f573fSAndroid Build Coastguard Worker return func() proto.Message { return new(googleMessage3.GoogleMessage3) } 37*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.google_message4.GoogleMessage4": 38*1b3f573fSAndroid Build Coastguard Worker return func() proto.Message { return new(googleMessage4.GoogleMessage4) } 39*1b3f573fSAndroid Build Coastguard Worker default: 40*1b3f573fSAndroid Build Coastguard Worker panic("Unknown message type: " + dataset.MessageName) 41*1b3f573fSAndroid Build Coastguard Worker } 42*1b3f573fSAndroid Build Coastguard Worker} 43*1b3f573fSAndroid Build Coastguard Worker 44*1b3f573fSAndroid Build Coastguard Workerfunc init() { 45*1b3f573fSAndroid Build Coastguard Worker flag.Parse() 46*1b3f573fSAndroid Build Coastguard Worker for _, f := range flag.Args() { 47*1b3f573fSAndroid Build Coastguard Worker // Load the benchmark. 48*1b3f573fSAndroid Build Coastguard Worker b, err := ioutil.ReadFile(f) 49*1b3f573fSAndroid Build Coastguard Worker if err != nil { 50*1b3f573fSAndroid Build Coastguard Worker panic(err) 51*1b3f573fSAndroid Build Coastguard Worker } 52*1b3f573fSAndroid Build Coastguard Worker 53*1b3f573fSAndroid Build Coastguard Worker // Parse the benchmark. 54*1b3f573fSAndroid Build Coastguard Worker var dm benchmarkWrapper.BenchmarkDataset 55*1b3f573fSAndroid Build Coastguard Worker if err := proto.Unmarshal(b, &dm); err != nil { 56*1b3f573fSAndroid Build Coastguard Worker panic(err) 57*1b3f573fSAndroid Build Coastguard Worker } 58*1b3f573fSAndroid Build Coastguard Worker 59*1b3f573fSAndroid Build Coastguard Worker // Determine the concrete protobuf message type to use. 60*1b3f573fSAndroid Build Coastguard Worker var ds Dataset 61*1b3f573fSAndroid Build Coastguard Worker ds.newMessage = generateNewMessageFunction(dm) 62*1b3f573fSAndroid Build Coastguard Worker 63*1b3f573fSAndroid Build Coastguard Worker // Unmarshal each test message. 64*1b3f573fSAndroid Build Coastguard Worker for _, payload := range dm.Payload { 65*1b3f573fSAndroid Build Coastguard Worker ds.marshaled = append(ds.marshaled, payload) 66*1b3f573fSAndroid Build Coastguard Worker m := ds.newMessage() 67*1b3f573fSAndroid Build Coastguard Worker if err := proto.Unmarshal(payload, m); err != nil { 68*1b3f573fSAndroid Build Coastguard Worker panic(err) 69*1b3f573fSAndroid Build Coastguard Worker } 70*1b3f573fSAndroid Build Coastguard Worker ds.unmarshaled = append(ds.unmarshaled, m) 71*1b3f573fSAndroid Build Coastguard Worker } 72*1b3f573fSAndroid Build Coastguard Worker ds.name = f 73*1b3f573fSAndroid Build Coastguard Worker 74*1b3f573fSAndroid Build Coastguard Worker datasets = append(datasets, ds) 75*1b3f573fSAndroid Build Coastguard Worker } 76*1b3f573fSAndroid Build Coastguard Worker} 77*1b3f573fSAndroid Build Coastguard Worker 78*1b3f573fSAndroid Build Coastguard Workerfunc Benchmark(b *testing.B) { 79*1b3f573fSAndroid Build Coastguard Worker for _, ds := range datasets { 80*1b3f573fSAndroid Build Coastguard Worker b.Run(ds.name, func(b *testing.B) { 81*1b3f573fSAndroid Build Coastguard Worker b.Run("Unmarshal", func(b *testing.B) { 82*1b3f573fSAndroid Build Coastguard Worker for i := 0; i < b.N; i++ { 83*1b3f573fSAndroid Build Coastguard Worker for j, payload := range ds.marshaled { 84*1b3f573fSAndroid Build Coastguard Worker out := ds.newMessage() 85*1b3f573fSAndroid Build Coastguard Worker if err := proto.Unmarshal(payload, out); err != nil { 86*1b3f573fSAndroid Build Coastguard Worker b.Fatalf("can't unmarshal message %d %v", j, err) 87*1b3f573fSAndroid Build Coastguard Worker } 88*1b3f573fSAndroid Build Coastguard Worker } 89*1b3f573fSAndroid Build Coastguard Worker } 90*1b3f573fSAndroid Build Coastguard Worker }) 91*1b3f573fSAndroid Build Coastguard Worker b.Run("Marshal", func(b *testing.B) { 92*1b3f573fSAndroid Build Coastguard Worker for i := 0; i < b.N; i++ { 93*1b3f573fSAndroid Build Coastguard Worker for j, m := range ds.unmarshaled { 94*1b3f573fSAndroid Build Coastguard Worker if _, err := proto.Marshal(m); err != nil { 95*1b3f573fSAndroid Build Coastguard Worker b.Fatalf("can't marshal message %d %+v: %v", j, m, err) 96*1b3f573fSAndroid Build Coastguard Worker } 97*1b3f573fSAndroid Build Coastguard Worker } 98*1b3f573fSAndroid Build Coastguard Worker } 99*1b3f573fSAndroid Build Coastguard Worker }) 100*1b3f573fSAndroid Build Coastguard Worker b.Run("Size", func(b *testing.B) { 101*1b3f573fSAndroid Build Coastguard Worker for i := 0; i < b.N; i++ { 102*1b3f573fSAndroid Build Coastguard Worker for _, m := range ds.unmarshaled { 103*1b3f573fSAndroid Build Coastguard Worker proto.Size(m) 104*1b3f573fSAndroid Build Coastguard Worker } 105*1b3f573fSAndroid Build Coastguard Worker } 106*1b3f573fSAndroid Build Coastguard Worker }) 107*1b3f573fSAndroid Build Coastguard Worker b.Run("Clone", func(b *testing.B) { 108*1b3f573fSAndroid Build Coastguard Worker for i := 0; i < b.N; i++ { 109*1b3f573fSAndroid Build Coastguard Worker for _, m := range ds.unmarshaled { 110*1b3f573fSAndroid Build Coastguard Worker proto.Clone(m) 111*1b3f573fSAndroid Build Coastguard Worker } 112*1b3f573fSAndroid Build Coastguard Worker } 113*1b3f573fSAndroid Build Coastguard Worker }) 114*1b3f573fSAndroid Build Coastguard Worker b.Run("Merge", func(b *testing.B) { 115*1b3f573fSAndroid Build Coastguard Worker for i := 0; i < b.N; i++ { 116*1b3f573fSAndroid Build Coastguard Worker for _, m := range ds.unmarshaled { 117*1b3f573fSAndroid Build Coastguard Worker out := ds.newMessage() 118*1b3f573fSAndroid Build Coastguard Worker proto.Merge(out, m) 119*1b3f573fSAndroid Build Coastguard Worker } 120*1b3f573fSAndroid Build Coastguard Worker } 121*1b3f573fSAndroid Build Coastguard Worker }) 122*1b3f573fSAndroid Build Coastguard Worker }) 123*1b3f573fSAndroid Build Coastguard Worker } 124*1b3f573fSAndroid Build Coastguard Worker} 125