go_benchmark_test.go 3.3 KB

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