OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / golang / protobuf / proto / decode_test.go
1 // Go support for Protocol Buffers - Google's data interchange format
2 //
3 // Copyright 2010 The Go Authors.  All rights reserved.
4 // https://github.com/golang/protobuf
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
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
15 // distribution.
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.
19 //
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.
31
32 // +build go1.7
33
34 package proto_test
35
36 import (
37         "fmt"
38         "testing"
39
40         "github.com/golang/protobuf/proto"
41         tpb "github.com/golang/protobuf/proto/proto3_proto"
42 )
43
44 var (
45         bytesBlackhole []byte
46         msgBlackhole   = new(tpb.Message)
47 )
48
49 // BenchmarkVarint32ArraySmall shows the performance on an array of small int32 fields (1 and
50 // 2 bytes long).
51 func BenchmarkVarint32ArraySmall(b *testing.B) {
52         for i := uint(1); i <= 10; i++ {
53                 dist := genInt32Dist([7]int{0, 3, 1}, 1<<i)
54                 raw, err := proto.Marshal(&tpb.Message{
55                         ShortKey: dist,
56                 })
57                 if err != nil {
58                         b.Error("wrong encode", err)
59                 }
60                 b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
61                         scratchBuf := proto.NewBuffer(nil)
62                         b.ResetTimer()
63                         for k := 0; k < b.N; k++ {
64                                 scratchBuf.SetBuf(raw)
65                                 msgBlackhole.Reset()
66                                 if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
67                                         b.Error("wrong decode", err)
68                                 }
69                         }
70                 })
71         }
72 }
73
74 // BenchmarkVarint32ArrayLarge shows the performance on an array of large int32 fields (3 and
75 // 4 bytes long, with a small number of 1, 2, 5 and 10 byte long versions).
76 func BenchmarkVarint32ArrayLarge(b *testing.B) {
77         for i := uint(1); i <= 10; i++ {
78                 dist := genInt32Dist([7]int{0, 1, 2, 4, 8, 1, 1}, 1<<i)
79                 raw, err := proto.Marshal(&tpb.Message{
80                         ShortKey: dist,
81                 })
82                 if err != nil {
83                         b.Error("wrong encode", err)
84                 }
85                 b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
86                         scratchBuf := proto.NewBuffer(nil)
87                         b.ResetTimer()
88                         for k := 0; k < b.N; k++ {
89                                 scratchBuf.SetBuf(raw)
90                                 msgBlackhole.Reset()
91                                 if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
92                                         b.Error("wrong decode", err)
93                                 }
94                         }
95                 })
96         }
97 }
98
99 // BenchmarkVarint64ArraySmall shows the performance on an array of small int64 fields (1 and
100 // 2 bytes long).
101 func BenchmarkVarint64ArraySmall(b *testing.B) {
102         for i := uint(1); i <= 10; i++ {
103                 dist := genUint64Dist([11]int{0, 3, 1}, 1<<i)
104                 raw, err := proto.Marshal(&tpb.Message{
105                         Key: dist,
106                 })
107                 if err != nil {
108                         b.Error("wrong encode", err)
109                 }
110                 b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
111                         scratchBuf := proto.NewBuffer(nil)
112                         b.ResetTimer()
113                         for k := 0; k < b.N; k++ {
114                                 scratchBuf.SetBuf(raw)
115                                 msgBlackhole.Reset()
116                                 if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
117                                         b.Error("wrong decode", err)
118                                 }
119                         }
120                 })
121         }
122 }
123
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{
130                         Key: dist,
131                 })
132                 if err != nil {
133                         b.Error("wrong encode", err)
134                 }
135                 b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
136                         scratchBuf := proto.NewBuffer(nil)
137                         b.ResetTimer()
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)
143                                 }
144                         }
145                 })
146         }
147 }
148
149 // BenchmarkVarint64ArrayMixed shows the performance of lots of small messages, each
150 // containing a small number of large (3, 4, and 5 byte) repeated int64s.
151 func BenchmarkVarint64ArrayMixed(b *testing.B) {
152         for i := uint(1); i <= 1<<5; i <<= 1 {
153                 dist := genUint64Dist([11]int{0, 0, 0, 4, 6, 4, 0, 0, 0, 0, 0}, int(i))
154                 // number of sub fields
155                 for k := uint(1); k <= 1<<10; k <<= 2 {
156                         msg := &tpb.Message{}
157                         for m := uint(0); m < k; m++ {
158                                 msg.Children = append(msg.Children, &tpb.Message{
159                                         Key: dist,
160                                 })
161                         }
162                         raw, err := proto.Marshal(msg)
163                         if err != nil {
164                                 b.Error("wrong encode", err)
165                         }
166                         b.Run(fmt.Sprintf("Fields%vLen%v", k, i), func(b *testing.B) {
167                                 scratchBuf := proto.NewBuffer(nil)
168                                 b.ResetTimer()
169                                 for k := 0; k < b.N; k++ {
170                                         scratchBuf.SetBuf(raw)
171                                         msgBlackhole.Reset()
172                                         if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
173                                                 b.Error("wrong decode", err)
174                                         }
175                                 }
176                         })
177                 }
178         }
179 }
180
181 // genInt32Dist generates a slice of ints that will match the size distribution of dist.
182 // A size of 6 corresponds to a max length varint32, which is 10 bytes.  The distribution
183 // is 1-indexed. (i.e. the value at index 1 is how many 1 byte ints to create).
184 func genInt32Dist(dist [7]int, count int) (dest []int32) {
185         for i := 0; i < count; i++ {
186                 for k := 0; k < len(dist); k++ {
187                         var num int32
188                         switch k {
189                         case 1:
190                                 num = 1<<7 - 1
191                         case 2:
192                                 num = 1<<14 - 1
193                         case 3:
194                                 num = 1<<21 - 1
195                         case 4:
196                                 num = 1<<28 - 1
197                         case 5:
198                                 num = 1<<29 - 1
199                         case 6:
200                                 num = -1
201                         }
202                         for m := 0; m < dist[k]; m++ {
203                                 dest = append(dest, num)
204                         }
205                 }
206         }
207         return
208 }
209
210 // genUint64Dist generates a slice of ints that will match the size distribution of dist.
211 // The distribution is 1-indexed. (i.e. the value at index 1 is how many 1 byte ints to create).
212 func genUint64Dist(dist [11]int, count int) (dest []uint64) {
213         for i := 0; i < count; i++ {
214                 for k := 0; k < len(dist); k++ {
215                         var num uint64
216                         switch k {
217                         case 1:
218                                 num = 1<<7 - 1
219                         case 2:
220                                 num = 1<<14 - 1
221                         case 3:
222                                 num = 1<<21 - 1
223                         case 4:
224                                 num = 1<<28 - 1
225                         case 5:
226                                 num = 1<<35 - 1
227                         case 6:
228                                 num = 1<<42 - 1
229                         case 7:
230                                 num = 1<<49 - 1
231                         case 8:
232                                 num = 1<<56 - 1
233                         case 9:
234                                 num = 1<<63 - 1
235                         case 10:
236                                 num = 1<<64 - 1
237                         }
238                         for m := 0; m < dist[k]; m++ {
239                                 dest = append(dest, num)
240                         }
241                 }
242         }
243         return
244 }
245
246 // BenchmarkDecodeEmpty measures the overhead of doing the minimal possible decode.
247 func BenchmarkDecodeEmpty(b *testing.B) {
248         raw, err := proto.Marshal(&tpb.Message{})
249         if err != nil {
250                 b.Error("wrong encode", err)
251         }
252         b.ResetTimer()
253         for i := 0; i < b.N; i++ {
254                 if err := proto.Unmarshal(raw, msgBlackhole); err != nil {
255                         b.Error("wrong decode", err)
256                 }
257         }
258 }