...

Source file src/github.com/gogo/protobuf/proto/decode_test.go

Documentation: github.com/gogo/protobuf/proto

     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  	"testing"
    38  
    39  	"github.com/gogo/protobuf/proto"
    40  	tpb "github.com/gogo/protobuf/proto/proto3_proto"
    41  )
    42  
    43  var msgBlackhole = new(tpb.Message)
    44  
    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
    47  // 2 bytes long).
    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{
    52  // 			ShortKey: dist,
    53  // 		})
    54  // 		if err != nil {
    55  // 			b.Error("wrong encode", err)
    56  // 		}
    57  // 		b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
    58  // 			scratchBuf := proto.NewBuffer(nil)
    59  // 			b.ResetTimer()
    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)
    65  // 				}
    66  // 			}
    67  // 		})
    68  // 	}
    69  // }
    70  
    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{
    78  // 			ShortKey: dist,
    79  // 		})
    80  // 		if err != nil {
    81  // 			b.Error("wrong encode", err)
    82  // 		}
    83  // 		b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
    84  // 			scratchBuf := proto.NewBuffer(nil)
    85  // 			b.ResetTimer()
    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)
    91  // 				}
    92  // 			}
    93  // 		})
    94  // 	}
    95  // }
    96  
    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
    99  // 2 bytes long).
   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{
   104  // 			Key: dist,
   105  // 		})
   106  // 		if err != nil {
   107  // 			b.Error("wrong encode", err)
   108  // 		}
   109  // 		b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
   110  // 			scratchBuf := proto.NewBuffer(nil)
   111  // 			b.ResetTimer()
   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)
   117  // 				}
   118  // 			}
   119  // 		})
   120  // 	}
   121  // }
   122  
   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{
   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  // 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{
   160  // 					Key: dist,
   161  // 				})
   162  // 			}
   163  // 			raw, err := proto.Marshal(msg)
   164  // 			if err != nil {
   165  // 				b.Error("wrong encode", err)
   166  // 			}
   167  // 			b.Run(fmt.Sprintf("Fields%vLen%v", k, i), func(b *testing.B) {
   168  // 				scratchBuf := proto.NewBuffer(nil)
   169  // 				b.ResetTimer()
   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)
   175  // 					}
   176  // 				}
   177  // 			})
   178  // 		}
   179  // 	}
   180  // }
   181  
   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++ {
   188  			var num int32
   189  			switch k {
   190  			case 1:
   191  				num = 1<<7 - 1
   192  			case 2:
   193  				num = 1<<14 - 1
   194  			case 3:
   195  				num = 1<<21 - 1
   196  			case 4:
   197  				num = 1<<28 - 1
   198  			case 5:
   199  				num = 1<<29 - 1
   200  			case 6:
   201  				num = -1
   202  			}
   203  			for m := 0; m < dist[k]; m++ {
   204  				dest = append(dest, num)
   205  			}
   206  		}
   207  	}
   208  	return
   209  }
   210  
   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++ {
   216  			var num uint64
   217  			switch k {
   218  			case 1:
   219  				num = 1<<7 - 1
   220  			case 2:
   221  				num = 1<<14 - 1
   222  			case 3:
   223  				num = 1<<21 - 1
   224  			case 4:
   225  				num = 1<<28 - 1
   226  			case 5:
   227  				num = 1<<35 - 1
   228  			case 6:
   229  				num = 1<<42 - 1
   230  			case 7:
   231  				num = 1<<49 - 1
   232  			case 8:
   233  				num = 1<<56 - 1
   234  			case 9:
   235  				num = 1<<63 - 1
   236  			case 10:
   237  				num = 1<<64 - 1
   238  			}
   239  			for m := 0; m < dist[k]; m++ {
   240  				dest = append(dest, num)
   241  			}
   242  		}
   243  	}
   244  	return
   245  }
   246  
   247  // BenchmarkDecodeEmpty measures the overhead of doing the minimal possible decode.
   248  func BenchmarkDecodeEmpty(b *testing.B) {
   249  	raw, err := proto.Marshal(&tpb.Message{})
   250  	if err != nil {
   251  		b.Error("wrong encode", err)
   252  	}
   253  	b.ResetTimer()
   254  	for i := 0; i < b.N; i++ {
   255  		if err := proto.Unmarshal(raw, msgBlackhole); err != nil {
   256  			b.Error("wrong decode", err)
   257  		}
   258  	}
   259  }
   260  

View as plain text