1 // Go support for Protocol Buffers - Google's data interchange format
3 // Copyright 2010 The Go Authors. All rights reserved.
4 // https://github.com/golang/protobuf
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
16 // * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 "github.com/gogo/protobuf/proto"
40 tpb "github.com/gogo/protobuf/proto/proto3_proto"
43 var msgBlackhole = new(tpb.Message)
45 // Disabled this Benchmark because it is using features (b.Run) from go1.7 and gogoprotobuf still have compatibility with go1.5
46 // BenchmarkVarint32ArraySmall shows the performance on an array of small int32 fields (1 and
48 // func BenchmarkVarint32ArraySmall(b *testing.B) {
49 // for i := uint(1); i <= 10; i++ {
50 // dist := genInt32Dist([7]int{0, 3, 1}, 1<<i)
51 // raw, err := proto.Marshal(&tpb.Message{
55 // b.Error("wrong encode", err)
57 // b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
58 // scratchBuf := proto.NewBuffer(nil)
60 // for k := 0; k < b.N; k++ {
61 // scratchBuf.SetBuf(raw)
62 // msgBlackhole.Reset()
63 // if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
64 // b.Error("wrong decode", err)
71 // Disabled this Benchmark because it is using features (b.Run) from go1.7 and gogoprotobuf still have compatibility with go1.5
72 // BenchmarkVarint32ArrayLarge shows the performance on an array of large int32 fields (3 and
73 // 4 bytes long, with a small number of 1, 2, 5 and 10 byte long versions).
74 // func BenchmarkVarint32ArrayLarge(b *testing.B) {
75 // for i := uint(1); i <= 10; i++ {
76 // dist := genInt32Dist([7]int{0, 1, 2, 4, 8, 1, 1}, 1<<i)
77 // raw, err := proto.Marshal(&tpb.Message{
81 // b.Error("wrong encode", err)
83 // b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
84 // scratchBuf := proto.NewBuffer(nil)
86 // for k := 0; k < b.N; k++ {
87 // scratchBuf.SetBuf(raw)
88 // msgBlackhole.Reset()
89 // if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
90 // b.Error("wrong decode", err)
97 // Disabled this Benchmark because it is using features (b.Run) from go1.7 and gogoprotobuf still have compatibility with go1.5
98 // BenchmarkVarint64ArraySmall shows the performance on an array of small int64 fields (1 and
100 // func BenchmarkVarint64ArraySmall(b *testing.B) {
101 // for i := uint(1); i <= 10; i++ {
102 // dist := genUint64Dist([11]int{0, 3, 1}, 1<<i)
103 // raw, err := proto.Marshal(&tpb.Message{
107 // b.Error("wrong encode", err)
109 // b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
110 // scratchBuf := proto.NewBuffer(nil)
112 // for k := 0; k < b.N; k++ {
113 // scratchBuf.SetBuf(raw)
114 // msgBlackhole.Reset()
115 // if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
116 // b.Error("wrong decode", err)
123 // Disabled this Benchmark because it is using features (b.Run) from go1.7 and gogoprotobuf still have compatibility with go1.5
124 // BenchmarkVarint64ArrayLarge shows the performance on an array of large int64 fields (6, 7,
125 // and 8 bytes long with a small number of the other sizes).
126 // func BenchmarkVarint64ArrayLarge(b *testing.B) {
127 // for i := uint(1); i <= 10; i++ {
128 // dist := genUint64Dist([11]int{0, 1, 1, 2, 4, 8, 16, 32, 16, 1, 1}, 1<<i)
129 // raw, err := proto.Marshal(&tpb.Message{
133 // b.Error("wrong encode", err)
135 // b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
136 // scratchBuf := proto.NewBuffer(nil)
138 // for k := 0; k < b.N; k++ {
139 // scratchBuf.SetBuf(raw)
140 // msgBlackhole.Reset()
141 // if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
142 // b.Error("wrong decode", err)
149 // Disabled this Benchmark because it is using features (b.Run) from go1.7 and gogoprotobuf still have compatibility with go1.5
150 // BenchmarkVarint64ArrayMixed shows the performance of lots of small messages, each
151 // containing a small number of large (3, 4, and 5 byte) repeated int64s.
152 // func BenchmarkVarint64ArrayMixed(b *testing.B) {
153 // for i := uint(1); i <= 1<<5; i <<= 1 {
154 // dist := genUint64Dist([11]int{0, 0, 0, 4, 6, 4, 0, 0, 0, 0, 0}, int(i))
155 // // number of sub fields
156 // for k := uint(1); k <= 1<<10; k <<= 2 {
157 // msg := &tpb.Message{}
158 // for m := uint(0); m < k; m++ {
159 // msg.Children = append(msg.Children, &tpb.Message{
163 // raw, err := proto.Marshal(msg)
165 // b.Error("wrong encode", err)
167 // b.Run(fmt.Sprintf("Fields%vLen%v", k, i), func(b *testing.B) {
168 // scratchBuf := proto.NewBuffer(nil)
170 // for k := 0; k < b.N; k++ {
171 // scratchBuf.SetBuf(raw)
172 // msgBlackhole.Reset()
173 // if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
174 // b.Error("wrong decode", err)
182 // genInt32Dist generates a slice of ints that will match the size distribution of dist.
183 // A size of 6 corresponds to a max length varint32, which is 10 bytes. The distribution
184 // is 1-indexed. (i.e. the value at index 1 is how many 1 byte ints to create).
185 func genInt32Dist(dist [7]int, count int) (dest []int32) {
186 for i := 0; i < count; i++ {
187 for k := 0; k < len(dist); k++ {
203 for m := 0; m < dist[k]; m++ {
204 dest = append(dest, num)
211 // genUint64Dist generates a slice of ints that will match the size distribution of dist.
212 // The distribution is 1-indexed. (i.e. the value at index 1 is how many 1 byte ints to create).
213 func genUint64Dist(dist [11]int, count int) (dest []uint64) {
214 for i := 0; i < count; i++ {
215 for k := 0; k < len(dist); k++ {
239 for m := 0; m < dist[k]; m++ {
240 dest = append(dest, num)
247 // BenchmarkDecodeEmpty measures the overhead of doing the minimal possible decode.
248 func BenchmarkDecodeEmpty(b *testing.B) {
249 raw, err := proto.Marshal(&tpb.Message{})
251 b.Error("wrong encode", err)
254 for i := 0; i < b.N; i++ {
255 if err := proto.Unmarshal(raw, msgBlackhole); err != nil {
256 b.Error("wrong decode", err)