From 4e3c41349383fa6275a18a1c9c462c209ab361a8 Mon Sep 17 00:00:00 2001 From: BSBandme Date: Wed, 7 Mar 2018 00:35:42 -0800 Subject: Add go benchmark --- benchmarks/Makefile.am | 102 ++++++++++++++-- benchmarks/README.md | 24 ++++ benchmarks/cpp_benchmark.cc | 4 +- .../benchmark_message1_proto2.proto | 78 ------------ .../benchmark_message1_proto3.proto | 78 ------------ .../dataset.google_message1_proto2.pb | Bin 289 -> 0 bytes .../dataset.google_message1_proto3.pb | Bin 289 -> 0 bytes .../proto2/benchmark_message1_proto2.proto | 78 ++++++++++++ .../proto2/dataset.google_message1_proto2.pb | Bin 0 -> 289 bytes .../proto3/benchmark_message1_proto3.proto | 78 ++++++++++++ .../proto3/dataset.google_message1_proto3.pb | Bin 0 -> 289 bytes benchmarks/go_benchmark_test.go | 135 +++++++++++++++++++++ benchmarks/py_benchmark.py | 4 +- 13 files changed, 410 insertions(+), 171 deletions(-) delete mode 100644 benchmarks/datasets/google_message1/benchmark_message1_proto2.proto delete mode 100644 benchmarks/datasets/google_message1/benchmark_message1_proto3.proto delete mode 100644 benchmarks/datasets/google_message1/dataset.google_message1_proto2.pb delete mode 100644 benchmarks/datasets/google_message1/dataset.google_message1_proto3.pb create mode 100644 benchmarks/datasets/google_message1/proto2/benchmark_message1_proto2.proto create mode 100644 benchmarks/datasets/google_message1/proto2/dataset.google_message1_proto2.pb create mode 100644 benchmarks/datasets/google_message1/proto3/benchmark_message1_proto3.proto create mode 100644 benchmarks/datasets/google_message1/proto3/dataset.google_message1_proto3.pb create mode 100644 benchmarks/go_benchmark_test.go (limited to 'benchmarks') diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am index 5aa35c66..f0cb9402 100644 --- a/benchmarks/Makefile.am +++ b/benchmarks/Makefile.am @@ -1,9 +1,11 @@ +benchmarks_protoc_inputs_benchmark_wrapper = \ + benchmarks.proto + benchmarks_protoc_inputs = \ - benchmarks.proto \ - datasets/google_message1/benchmark_message1_proto3.proto + datasets/google_message1/proto3/benchmark_message1_proto3.proto benchmarks_protoc_inputs_proto2 = \ - datasets/google_message1/benchmark_message1_proto2.proto \ + datasets/google_message1/proto2/benchmark_message1_proto2.proto \ datasets/google_message2/benchmark_message2.proto \ datasets/google_message3/benchmark_message3.proto \ datasets/google_message3/benchmark_message3_1.proto \ @@ -26,7 +28,7 @@ make_tmp_dir: if USE_EXTERNAL_PROTOC protoc_middleman: make_tmp_dir $(benchmarks_protoc_inputs) - $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=./tmp $(benchmarks_protoc_inputs) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=./tmp $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) touch protoc_middleman protoc_middleman2: make_tmp_dir $(benchmarks_protoc_inputs_proto2) @@ -38,8 +40,8 @@ else # We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is # relative to srcdir, which may not be the same as the current directory when # building out-of-tree. -protoc_middleman: make_tmp_dir $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs) $(well_known_type_protoc_inputs) - oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd/tmp/java/src/main/java --python_out=$$oldpwd/tmp $(benchmarks_protoc_inputs) ) +protoc_middleman: make_tmp_dir $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs) $(well_known_type_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd/tmp/java/src/main/java --python_out=$$oldpwd/tmp $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) ) touch protoc_middleman protoc_middleman2: make_tmp_dir $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs_proto2) $(well_known_type_protoc_inputs) @@ -54,14 +56,14 @@ all_data = `find . -type f -name "dataset.*.pb"` benchmarks_protoc_outputs = \ benchmarks.pb.cc \ - datasets/google_message1/benchmark_message1_proto3.pb.cc + datasets/google_message1/proto3/benchmark_message1_proto3.pb.cc benchmarks_protoc_outputs_header = \ benchmarks.pb.h \ - datasets/google_message1/benchmark_message1_proto3.pb.h + datasets/google_message1/proto3/benchmark_message1_proto3.pb.h benchmarks_protoc_outputs_proto2_header = \ - datasets/google_message1/benchmark_message1_proto2.pb.h \ + datasets/google_message1/proto2/benchmark_message1_proto2.pb.h \ datasets/google_message2/benchmark_message2.pb.h \ datasets/google_message3/benchmark_message3.pb.h \ datasets/google_message3/benchmark_message3_1.pb.h \ @@ -78,7 +80,7 @@ benchmarks_protoc_outputs_proto2_header = \ datasets/google_message4/benchmark_message4_3.pb.h benchmarks_protoc_outputs_proto2 = \ - datasets/google_message1/benchmark_message1_proto2.pb.cc \ + datasets/google_message1/proto2/benchmark_message1_proto2.pb.cc \ datasets/google_message2/benchmark_message2.pb.cc \ datasets/google_message3/benchmark_message3.pb.cc \ datasets/google_message3/benchmark_message3_1.pb.cc \ @@ -224,6 +226,81 @@ python-cpp-generated-code: python-cpp-generated-code-benchmark ############# PYTHON RULES END ############## +############# GO RULES BEGIN ############## + +benchmarks_protoc_inputs_proto2_message1 = \ + datasets/google_message1/proto2/benchmark_message1_proto2.proto + +benchmarks_protoc_inputs_proto2_message2 = \ + datasets/google_message2/benchmark_message2.proto + +benchmarks_protoc_inputs_proto2_message3 = \ + datasets/google_message3/benchmark_message3.proto \ + datasets/google_message3/benchmark_message3_1.proto \ + datasets/google_message3/benchmark_message3_2.proto \ + datasets/google_message3/benchmark_message3_3.proto \ + datasets/google_message3/benchmark_message3_4.proto \ + datasets/google_message3/benchmark_message3_5.proto \ + datasets/google_message3/benchmark_message3_6.proto \ + datasets/google_message3/benchmark_message3_7.proto \ + datasets/google_message3/benchmark_message3_8.proto + +benchmarks_protoc_inputs_proto2_message4 = \ + datasets/google_message4/benchmark_message4.proto \ + datasets/google_message4/benchmark_message4_1.proto \ + datasets/google_message4/benchmark_message4_2.proto \ + datasets/google_message4/benchmark_message4_3.proto + +if USE_EXTERNAL_PROTOC + +go_protoc_middleman: make_tmp_dir $(benchmarks_protoc_inputs) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_benchmark_wrapper) + touch protoc_middleman + +go_protoc_middleman2: make_tmp_dir $(benchmarks_protoc_inputs_proto2_message1) $(benchmarks_protoc_inputs_proto2_message2) $(benchmarks_protoc_inputs_proto2_message3) $(benchmarks_protoc_inputs_proto2_message4) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2_message1) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2_message2) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2_message3) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2_message4) + touch protoc_middleman2 + +else + +# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is +# relative to srcdir, which may not be the same as the current directory when +# building out-of-tree. +go_protoc_middleman: make_tmp_dir $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs) $(well_known_type_protoc_inputs) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_benchmark_wrapper) ) + touch protoc_middleman + +go_protoc_middleman2: make_tmp_dir $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs_proto2_message1) $(benchmarks_protoc_inputs_proto2_message2) $(benchmarks_protoc_inputs_proto2_message3) $(benchmarks_protoc_inputs_proto2_message4) $(well_known_type_protoc_inputs) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2_message1) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2_message2) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2_message3) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --go_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2_message4) ) + touch protoc_middleman2 + +endif + +go-benchmark: go_protoc_middleman go_protoc_middleman2 + @echo "Writing shortcut script go-benchmark..." + @echo '#! /bin/sh' > go-benchmark + @echo 'mkdir tmp_cc && mv *.cc tmp_cc' >> go-benchmark + @echo 'for file in $$@; do' >> go-benchmark + @echo ' echo "Testing go benchmark for data file: $$file";' >> go-benchmark + @echo ' go test -bench=. -- $$file;' >> go-benchmark + @echo 'done' >> go-benchmark + @echo 'mv tmp_cc/* . && rm -rf tmp_cc' >> go-benchmark + @chmod +x go-benchmark + +go: go_protoc_middleman go_protoc_middleman2 go-benchmark + ./go-benchmark $(all_data) + +############# GO RULES END ############## + + MAINTAINERCLEANFILES = \ Makefile.in @@ -241,7 +318,10 @@ CLEANFILES = \ python_cpp_proto_library \ python-pure-python-benchmark \ python-cpp-reflection-benchmark \ - python-cpp-generated-code-benchmark + python-cpp-generated-code-benchmark \ + go-benchmark \ + go_protoc_middleman \ + go_protoc_middleman2 clean-local: -rm -rf tmp/* diff --git a/benchmarks/README.md b/benchmarks/README.md index 459c7b9d..183280ff 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -36,6 +36,18 @@ $ sudo apt-get install python3-dev ``` And you also need to make sure `pkg-config` is installed. +### Go +Golang protobuf is under [golang repo](https://github.com/golang/protobuf), you +need to install golang and golang protobuf's proto and protoc-gen-go before +running the benchmark. And we're using [testing package](https://golang.org/pkg/testing/) +to test benchmark. + +To install golang protobuf proto and protoc-gen-go, you can +``` +$ go get -u github.com/golang/protobuf/protoc-gen-go +$ go get -u github.com/golang/protobuf/proto +``` + ### Big data There's some optional big testing data which is not included in the directory @@ -87,6 +99,11 @@ $ make python-cpp-reflection $ make python-cpp-generated-code ``` +### Go +``` +$ make go +``` + To run a specific dataset: ### Java: @@ -126,6 +143,13 @@ $ make python-cpp-generated-code-benchmark $ ./python-cpp-generated-code-benchmark $(specific generated dataset file name) ``` +### Go: +``` +$ make go-benchmark +$ ./go-benchmark $(specific generated dataset file name) +``` + + ## Benchmark datasets Each data set is in the format of benchmarks.proto: diff --git a/benchmarks/cpp_benchmark.cc b/benchmarks/cpp_benchmark.cc index 0ba4dc52..f8b55291 100644 --- a/benchmarks/cpp_benchmark.cc +++ b/benchmarks/cpp_benchmark.cc @@ -32,8 +32,8 @@ #include #include "benchmark/benchmark_api.h" #include "benchmarks.pb.h" -#include "datasets/google_message1/benchmark_message1_proto2.pb.h" -#include "datasets/google_message1/benchmark_message1_proto3.pb.h" +#include "datasets/google_message1/proto2/benchmark_message1_proto2.pb.h" +#include "datasets/google_message1/proto3/benchmark_message1_proto3.pb.h" #include "datasets/google_message2/benchmark_message2.pb.h" #include "datasets/google_message3/benchmark_message3.pb.h" #include "datasets/google_message4/benchmark_message4.pb.h" diff --git a/benchmarks/datasets/google_message1/benchmark_message1_proto2.proto b/benchmarks/datasets/google_message1/benchmark_message1_proto2.proto deleted file mode 100644 index 21261905..00000000 --- a/benchmarks/datasets/google_message1/benchmark_message1_proto2.proto +++ /dev/null @@ -1,78 +0,0 @@ -// Benchmark messages for proto2. - -syntax = "proto2"; - -package benchmarks.proto2; -option java_package = "com.google.protobuf.benchmarks"; - -// This is the default, but we specify it here explicitly. -option optimize_for = SPEED; - -option cc_enable_arenas = true; - -message GoogleMessage1 { - required string field1 = 1; - optional string field9 = 9; - optional string field18 = 18; - optional bool field80 = 80 [default = false]; - optional bool field81 = 81 [default = true]; - required int32 field2 = 2; - required int32 field3 = 3; - optional int32 field280 = 280; - optional int32 field6 = 6 [default = 0]; - optional int64 field22 = 22; - optional string field4 = 4; - repeated fixed64 field5 = 5; - optional bool field59 = 59 [default = false]; - optional string field7 = 7; - optional int32 field16 = 16; - optional int32 field130 = 130 [default = 0]; - optional bool field12 = 12 [default = true]; - optional bool field17 = 17 [default = true]; - optional bool field13 = 13 [default = true]; - optional bool field14 = 14 [default = true]; - optional int32 field104 = 104 [default = 0]; - optional int32 field100 = 100 [default = 0]; - optional int32 field101 = 101 [default = 0]; - optional string field102 = 102; - optional string field103 = 103; - optional int32 field29 = 29 [default = 0]; - optional bool field30 = 30 [default = false]; - optional int32 field60 = 60 [default = -1]; - optional int32 field271 = 271 [default = -1]; - optional int32 field272 = 272 [default = -1]; - optional int32 field150 = 150; - optional int32 field23 = 23 [default = 0]; - optional bool field24 = 24 [default = false]; - optional int32 field25 = 25 [default = 0]; - optional GoogleMessage1SubMessage field15 = 15; - optional bool field78 = 78; - optional int32 field67 = 67 [default = 0]; - optional int32 field68 = 68; - optional int32 field128 = 128 [default = 0]; - optional string field129 = 129 [default = "xxxxxxxxxxxxxxxxxxxxx"]; - optional int32 field131 = 131 [default = 0]; -} - -message GoogleMessage1SubMessage { - optional int32 field1 = 1 [default = 0]; - optional int32 field2 = 2 [default = 0]; - optional int32 field3 = 3 [default = 0]; - optional string field15 = 15; - optional bool field12 = 12 [default = true]; - optional int64 field13 = 13; - optional int64 field14 = 14; - optional int32 field16 = 16; - optional int32 field19 = 19 [default = 2]; - optional bool field20 = 20 [default = true]; - optional bool field28 = 28 [default = true]; - optional fixed64 field21 = 21; - optional int32 field22 = 22; - optional bool field23 = 23 [default = false]; - optional bool field206 = 206 [default = false]; - optional fixed32 field203 = 203; - optional int32 field204 = 204; - optional string field205 = 205; - optional uint64 field207 = 207; - optional uint64 field300 = 300; -} diff --git a/benchmarks/datasets/google_message1/benchmark_message1_proto3.proto b/benchmarks/datasets/google_message1/benchmark_message1_proto3.proto deleted file mode 100644 index 090b554b..00000000 --- a/benchmarks/datasets/google_message1/benchmark_message1_proto3.proto +++ /dev/null @@ -1,78 +0,0 @@ -// Benchmark messages for proto3. - -syntax = "proto3"; - -package benchmarks.proto3; -option java_package = "com.google.protobuf.benchmarks"; - -// This is the default, but we specify it here explicitly. -option optimize_for = SPEED; - -option cc_enable_arenas = true; - -message GoogleMessage1 { - string field1 = 1; - string field9 = 9; - string field18 = 18; - bool field80 = 80; - bool field81 = 81; - int32 field2 = 2; - int32 field3 = 3; - int32 field280 = 280; - int32 field6 = 6; - int64 field22 = 22; - string field4 = 4; - repeated fixed64 field5 = 5; - bool field59 = 59; - string field7 = 7; - int32 field16 = 16; - int32 field130 = 130; - bool field12 = 12; - bool field17 = 17; - bool field13 = 13; - bool field14 = 14; - int32 field104 = 104; - int32 field100 = 100; - int32 field101 = 101; - string field102 = 102; - string field103 = 103; - int32 field29 = 29; - bool field30 = 30; - int32 field60 = 60; - int32 field271 = 271; - int32 field272 = 272; - int32 field150 = 150; - int32 field23 = 23; - bool field24 = 24; - int32 field25 = 25; - GoogleMessage1SubMessage field15 = 15; - bool field78 = 78; - int32 field67 = 67; - int32 field68 = 68; - int32 field128 = 128; - string field129 = 129; - int32 field131 = 131; -} - -message GoogleMessage1SubMessage { - int32 field1 = 1; - int32 field2 = 2; - int32 field3 = 3; - string field15 = 15; - bool field12 = 12; - int64 field13 = 13; - int64 field14 = 14; - int32 field16 = 16; - int32 field19 = 19; - bool field20 = 20; - bool field28 = 28; - fixed64 field21 = 21; - int32 field22 = 22; - bool field23 = 23; - bool field206 = 206; - fixed32 field203 = 203; - int32 field204 = 204; - string field205 = 205; - uint64 field207 = 207; - uint64 field300 = 300; -} diff --git a/benchmarks/datasets/google_message1/dataset.google_message1_proto2.pb b/benchmarks/datasets/google_message1/dataset.google_message1_proto2.pb deleted file mode 100644 index f6fe7848..00000000 Binary files a/benchmarks/datasets/google_message1/dataset.google_message1_proto2.pb and /dev/null differ diff --git a/benchmarks/datasets/google_message1/dataset.google_message1_proto3.pb b/benchmarks/datasets/google_message1/dataset.google_message1_proto3.pb deleted file mode 100644 index 4955bed3..00000000 Binary files a/benchmarks/datasets/google_message1/dataset.google_message1_proto3.pb and /dev/null differ diff --git a/benchmarks/datasets/google_message1/proto2/benchmark_message1_proto2.proto b/benchmarks/datasets/google_message1/proto2/benchmark_message1_proto2.proto new file mode 100644 index 00000000..21261905 --- /dev/null +++ b/benchmarks/datasets/google_message1/proto2/benchmark_message1_proto2.proto @@ -0,0 +1,78 @@ +// Benchmark messages for proto2. + +syntax = "proto2"; + +package benchmarks.proto2; +option java_package = "com.google.protobuf.benchmarks"; + +// This is the default, but we specify it here explicitly. +option optimize_for = SPEED; + +option cc_enable_arenas = true; + +message GoogleMessage1 { + required string field1 = 1; + optional string field9 = 9; + optional string field18 = 18; + optional bool field80 = 80 [default = false]; + optional bool field81 = 81 [default = true]; + required int32 field2 = 2; + required int32 field3 = 3; + optional int32 field280 = 280; + optional int32 field6 = 6 [default = 0]; + optional int64 field22 = 22; + optional string field4 = 4; + repeated fixed64 field5 = 5; + optional bool field59 = 59 [default = false]; + optional string field7 = 7; + optional int32 field16 = 16; + optional int32 field130 = 130 [default = 0]; + optional bool field12 = 12 [default = true]; + optional bool field17 = 17 [default = true]; + optional bool field13 = 13 [default = true]; + optional bool field14 = 14 [default = true]; + optional int32 field104 = 104 [default = 0]; + optional int32 field100 = 100 [default = 0]; + optional int32 field101 = 101 [default = 0]; + optional string field102 = 102; + optional string field103 = 103; + optional int32 field29 = 29 [default = 0]; + optional bool field30 = 30 [default = false]; + optional int32 field60 = 60 [default = -1]; + optional int32 field271 = 271 [default = -1]; + optional int32 field272 = 272 [default = -1]; + optional int32 field150 = 150; + optional int32 field23 = 23 [default = 0]; + optional bool field24 = 24 [default = false]; + optional int32 field25 = 25 [default = 0]; + optional GoogleMessage1SubMessage field15 = 15; + optional bool field78 = 78; + optional int32 field67 = 67 [default = 0]; + optional int32 field68 = 68; + optional int32 field128 = 128 [default = 0]; + optional string field129 = 129 [default = "xxxxxxxxxxxxxxxxxxxxx"]; + optional int32 field131 = 131 [default = 0]; +} + +message GoogleMessage1SubMessage { + optional int32 field1 = 1 [default = 0]; + optional int32 field2 = 2 [default = 0]; + optional int32 field3 = 3 [default = 0]; + optional string field15 = 15; + optional bool field12 = 12 [default = true]; + optional int64 field13 = 13; + optional int64 field14 = 14; + optional int32 field16 = 16; + optional int32 field19 = 19 [default = 2]; + optional bool field20 = 20 [default = true]; + optional bool field28 = 28 [default = true]; + optional fixed64 field21 = 21; + optional int32 field22 = 22; + optional bool field23 = 23 [default = false]; + optional bool field206 = 206 [default = false]; + optional fixed32 field203 = 203; + optional int32 field204 = 204; + optional string field205 = 205; + optional uint64 field207 = 207; + optional uint64 field300 = 300; +} diff --git a/benchmarks/datasets/google_message1/proto2/dataset.google_message1_proto2.pb b/benchmarks/datasets/google_message1/proto2/dataset.google_message1_proto2.pb new file mode 100644 index 00000000..f6fe7848 Binary files /dev/null and b/benchmarks/datasets/google_message1/proto2/dataset.google_message1_proto2.pb differ diff --git a/benchmarks/datasets/google_message1/proto3/benchmark_message1_proto3.proto b/benchmarks/datasets/google_message1/proto3/benchmark_message1_proto3.proto new file mode 100644 index 00000000..090b554b --- /dev/null +++ b/benchmarks/datasets/google_message1/proto3/benchmark_message1_proto3.proto @@ -0,0 +1,78 @@ +// Benchmark messages for proto3. + +syntax = "proto3"; + +package benchmarks.proto3; +option java_package = "com.google.protobuf.benchmarks"; + +// This is the default, but we specify it here explicitly. +option optimize_for = SPEED; + +option cc_enable_arenas = true; + +message GoogleMessage1 { + string field1 = 1; + string field9 = 9; + string field18 = 18; + bool field80 = 80; + bool field81 = 81; + int32 field2 = 2; + int32 field3 = 3; + int32 field280 = 280; + int32 field6 = 6; + int64 field22 = 22; + string field4 = 4; + repeated fixed64 field5 = 5; + bool field59 = 59; + string field7 = 7; + int32 field16 = 16; + int32 field130 = 130; + bool field12 = 12; + bool field17 = 17; + bool field13 = 13; + bool field14 = 14; + int32 field104 = 104; + int32 field100 = 100; + int32 field101 = 101; + string field102 = 102; + string field103 = 103; + int32 field29 = 29; + bool field30 = 30; + int32 field60 = 60; + int32 field271 = 271; + int32 field272 = 272; + int32 field150 = 150; + int32 field23 = 23; + bool field24 = 24; + int32 field25 = 25; + GoogleMessage1SubMessage field15 = 15; + bool field78 = 78; + int32 field67 = 67; + int32 field68 = 68; + int32 field128 = 128; + string field129 = 129; + int32 field131 = 131; +} + +message GoogleMessage1SubMessage { + int32 field1 = 1; + int32 field2 = 2; + int32 field3 = 3; + string field15 = 15; + bool field12 = 12; + int64 field13 = 13; + int64 field14 = 14; + int32 field16 = 16; + int32 field19 = 19; + bool field20 = 20; + bool field28 = 28; + fixed64 field21 = 21; + int32 field22 = 22; + bool field23 = 23; + bool field206 = 206; + fixed32 field203 = 203; + int32 field204 = 204; + string field205 = 205; + uint64 field207 = 207; + uint64 field300 = 300; +} diff --git a/benchmarks/datasets/google_message1/proto3/dataset.google_message1_proto3.pb b/benchmarks/datasets/google_message1/proto3/dataset.google_message1_proto3.pb new file mode 100644 index 00000000..4955bed3 Binary files /dev/null and b/benchmarks/datasets/google_message1/proto3/dataset.google_message1_proto3.pb differ diff --git a/benchmarks/go_benchmark_test.go b/benchmarks/go_benchmark_test.go new file mode 100644 index 00000000..6f10d813 --- /dev/null +++ b/benchmarks/go_benchmark_test.go @@ -0,0 +1,135 @@ +package main + +import ( + "errors" + "io/ioutil" + "flag" + "testing" + "os" + + benchmarkWrapper "./tmp" + proto "github.com/golang/protobuf/proto" + googleMessage1Proto3 "./tmp/datasets/google_message1/proto3" + googleMessage1Proto2 "./tmp/datasets/google_message1/proto2" + googleMessage2 "./tmp/datasets/google_message2" + googleMessage3 "./tmp/datasets/google_message3" + googleMessage4 "./tmp/datasets/google_message4" + +) + +// Data is returned by the Load function. +type Data struct { + // Marshalled is a slice of marshalled protocol + // buffers. 1:1 with Unmarshalled. + Marshalled [][]byte + + // Unmarshalled is a slice of unmarshalled protocol + // buffers. 1:1 with Marshalled. + Unmarshalled []proto.Message + + count int +} + +var data *Data +var counter int + +type GetDefaultInstanceFunction func() proto.Message +var getDefaultInstance GetDefaultInstanceFunction + +// This is used to getDefaultInstance for a message type. +func generateGetDefaltInstanceFunction(dataset benchmarkWrapper.BenchmarkDataset) error { + switch dataset.MessageName { + case "benchmarks.proto3.GoogleMessage1": + getDefaultInstance = func() proto.Message { return &googleMessage1Proto3.GoogleMessage1{} } + return nil + case "benchmarks.proto2.GoogleMessage1": + getDefaultInstance = func() proto.Message { return &googleMessage1Proto2.GoogleMessage1{} } + return nil + case "benchmarks.proto2.GoogleMessage2": + getDefaultInstance = func() proto.Message { return &googleMessage2.GoogleMessage2{} } + return nil + case "benchmarks.google_message3.GoogleMessage3": + getDefaultInstance = func() proto.Message { return &googleMessage3.GoogleMessage3{} } + return nil + case "benchmarks.google_message4.GoogleMessage4": + getDefaultInstance = func() proto.Message { return &googleMessage4.GoogleMessage4{} } + return nil + default: + return errors.New("Unknown message type: " + dataset.MessageName) + } +} + +func TestMain(m *testing.M) { + flag.Parse() + data = new(Data) + rawData, error := ioutil.ReadFile(flag.Arg(0)) + if error != nil { + panic("Couldn't find file" + flag.Arg(0)) + } + var dataset benchmarkWrapper.BenchmarkDataset + + if err1 := proto.Unmarshal(rawData, &dataset); err1 != nil { + panic("The raw input data can't be parse into BenchmarkDataset message.") + } + + generateGetDefaltInstanceFunction(dataset) + + for _, payload := range dataset.Payload { + data.Marshalled = append(data.Marshalled, payload) + m := getDefaultInstance() + proto.Unmarshal(payload, m) + data.Unmarshalled = append(data.Unmarshalled, m) + } + data.count = len(data.Unmarshalled) + + os.Exit(m.Run()) +} + +func BenchmarkUnmarshal(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + payload := data.Marshalled[counter % data.count] + out := getDefaultInstance() + if err := proto.Unmarshal(payload, out); err != nil { + b.Fatalf("can't unmarshal message %d %v", counter % data.count, err) + } + counter++ + } +} + +func BenchmarkMarshal(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + m := data.Unmarshalled[counter % data.count] + if _, err := proto.Marshal(m); err != nil { + b.Fatalf("can't marshal message %d %+v: %v", counter % data.count, m, err) + } + counter++ + } +} + +func BenchmarkSize(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + proto.Size(data.Unmarshalled[counter % data.count]) + counter++ + } +} + +func BenchmarkClone(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + proto.Clone(data.Unmarshalled[counter % data.count]) + counter++ + } +} + +func BenchmarkMerge(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + out := getDefaultInstance() + proto.Merge(out, data.Unmarshalled[counter % data.count]) + counter++ + } +} + diff --git a/benchmarks/py_benchmark.py b/benchmarks/py_benchmark.py index 48234f03..8858f4aa 100755 --- a/benchmarks/py_benchmark.py +++ b/benchmarks/py_benchmark.py @@ -17,8 +17,8 @@ elif sys.argv[1] != "false": raise IOError("Need string argument \"true\" or \"false\" for whether to use cpp generated code") # END CPP GENERATED MESSAGE -import datasets.google_message1.benchmark_message1_proto2_pb2 as benchmark_message1_proto2_pb2 -import datasets.google_message1.benchmark_message1_proto3_pb2 as benchmark_message1_proto3_pb2 +import datasets.google_message1.proto2.benchmark_message1_proto2_pb2 as benchmark_message1_proto2_pb2 +import datasets.google_message1.proto3.benchmark_message1_proto3_pb2 as benchmark_message1_proto3_pb2 import datasets.google_message2.benchmark_message2_pb2 as benchmark_message2_pb2 import datasets.google_message3.benchmark_message3_pb2 as benchmark_message3_pb2 import datasets.google_message4.benchmark_message4_pb2 as benchmark_message4_pb2 -- cgit v1.2.3 From 6d2c6a0099e75eddacb8289053dd1cb96fc60368 Mon Sep 17 00:00:00 2001 From: BSBandme Date: Tue, 13 Mar 2018 01:18:20 -0700 Subject: some fix --- benchmarks/README.md | 15 ++++++----- benchmarks/go_benchmark_test.go | 56 ++++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 35 deletions(-) (limited to 'benchmarks') diff --git a/benchmarks/README.md b/benchmarks/README.md index 183280ff..74c042d8 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -37,17 +37,20 @@ $ sudo apt-get install python3-dev And you also need to make sure `pkg-config` is installed. ### Go -Golang protobuf is under [golang repo](https://github.com/golang/protobuf), you -need to install golang and golang protobuf's proto and protoc-gen-go before -running the benchmark. And we're using [testing package](https://golang.org/pkg/testing/) -to test benchmark. +Go protobufs are maintained at [github.com/golang/protobuf]( +http://github.com/golang/protobuf). If not done already, you need to install the +toolchain and the Go protoc-gen-go plugin for protoc. + +To install protoc-gen-go, run: -To install golang protobuf proto and protoc-gen-go, you can ``` $ go get -u github.com/golang/protobuf/protoc-gen-go -$ go get -u github.com/golang/protobuf/proto +$ export PATH=$PATH:$(go env GOPATH)/bin ``` +The first command installs `protoc-gen-go` into the `bin` directory in your local `GOPATH`. +The second command adds the `bin` directory to your `PATH` so that `protoc` can locate the plugin later. + ### Big data There's some optional big testing data which is not included in the directory diff --git a/benchmarks/go_benchmark_test.go b/benchmarks/go_benchmark_test.go index 6f10d813..59d5856b 100644 --- a/benchmarks/go_benchmark_test.go +++ b/benchmarks/go_benchmark_test.go @@ -1,31 +1,29 @@ package main import ( - "errors" - "io/ioutil" - "flag" - "testing" - "os" - benchmarkWrapper "./tmp" - proto "github.com/golang/protobuf/proto" - googleMessage1Proto3 "./tmp/datasets/google_message1/proto3" googleMessage1Proto2 "./tmp/datasets/google_message1/proto2" + googleMessage1Proto3 "./tmp/datasets/google_message1/proto3" googleMessage2 "./tmp/datasets/google_message2" googleMessage3 "./tmp/datasets/google_message3" googleMessage4 "./tmp/datasets/google_message4" - + "errors" + "flag" + "github.com/golang/protobuf/proto" + "io/ioutil" + "os" + "testing" ) // Data is returned by the Load function. type Data struct { - // Marshalled is a slice of marshalled protocol - // buffers. 1:1 with Unmarshalled. - Marshalled [][]byte + // marshaled is a slice of marshaled protocol + // buffers. 1:1 with unmarshaled. + marshaled [][]byte - // Unmarshalled is a slice of unmarshalled protocol - // buffers. 1:1 with Marshalled. - Unmarshalled []proto.Message + // Unmarshaled is a slice of unmarshaled protocol + // buffers. 1:1 with marshaled. + unmarshaled []proto.Message count int } @@ -34,6 +32,7 @@ var data *Data var counter int type GetDefaultInstanceFunction func() proto.Message + var getDefaultInstance GetDefaultInstanceFunction // This is used to getDefaultInstance for a message type. @@ -62,25 +61,25 @@ func generateGetDefaltInstanceFunction(dataset benchmarkWrapper.BenchmarkDataset func TestMain(m *testing.M) { flag.Parse() data = new(Data) - rawData, error := ioutil.ReadFile(flag.Arg(0)) - if error != nil { + rawData, err := ioutil.ReadFile(flag.Arg(0)) + if err != nil { panic("Couldn't find file" + flag.Arg(0)) } var dataset benchmarkWrapper.BenchmarkDataset - if err1 := proto.Unmarshal(rawData, &dataset); err1 != nil { + if err = proto.Unmarshal(rawData, &dataset); err != nil { panic("The raw input data can't be parse into BenchmarkDataset message.") } generateGetDefaltInstanceFunction(dataset) for _, payload := range dataset.Payload { - data.Marshalled = append(data.Marshalled, payload) + data.marshaled = append(data.marshaled, payload) m := getDefaultInstance() proto.Unmarshal(payload, m) - data.Unmarshalled = append(data.Unmarshalled, m) + data.unmarshaled = append(data.unmarshaled, m) } - data.count = len(data.Unmarshalled) + data.count = len(data.unmarshaled) os.Exit(m.Run()) } @@ -88,10 +87,10 @@ func TestMain(m *testing.M) { func BenchmarkUnmarshal(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - payload := data.Marshalled[counter % data.count] + payload := data.marshaled[counter%data.count] out := getDefaultInstance() if err := proto.Unmarshal(payload, out); err != nil { - b.Fatalf("can't unmarshal message %d %v", counter % data.count, err) + b.Fatalf("can't unmarshal message %d %v", counter%data.count, err) } counter++ } @@ -100,9 +99,9 @@ func BenchmarkUnmarshal(b *testing.B) { func BenchmarkMarshal(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - m := data.Unmarshalled[counter % data.count] + m := data.unmarshaled[counter%data.count] if _, err := proto.Marshal(m); err != nil { - b.Fatalf("can't marshal message %d %+v: %v", counter % data.count, m, err) + b.Fatalf("can't marshal message %d %+v: %v", counter%data.count, m, err) } counter++ } @@ -111,7 +110,7 @@ func BenchmarkMarshal(b *testing.B) { func BenchmarkSize(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - proto.Size(data.Unmarshalled[counter % data.count]) + proto.Size(data.unmarshaled[counter%data.count]) counter++ } } @@ -119,7 +118,7 @@ func BenchmarkSize(b *testing.B) { func BenchmarkClone(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - proto.Clone(data.Unmarshalled[counter % data.count]) + proto.Clone(data.unmarshaled[counter%data.count]) counter++ } } @@ -128,8 +127,7 @@ func BenchmarkMerge(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { out := getDefaultInstance() - proto.Merge(out, data.Unmarshalled[counter % data.count]) + proto.Merge(out, data.unmarshaled[counter%data.count]) counter++ } } - -- cgit v1.2.3 From 501c13f65a0093b61d95e16e8941cd3b456c41a0 Mon Sep 17 00:00:00 2001 From: BSBandme Date: Wed, 14 Mar 2018 07:03:44 -0700 Subject: Rewrite go_benchmark --- benchmarks/Makefile.am | 5 +- benchmarks/go_benchmark_test.go | 172 +++++++++++++++++++--------------------- 2 files changed, 82 insertions(+), 95 deletions(-) (limited to 'benchmarks') diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am index f0cb9402..3de0e380 100644 --- a/benchmarks/Makefile.am +++ b/benchmarks/Makefile.am @@ -288,10 +288,7 @@ go-benchmark: go_protoc_middleman go_protoc_middleman2 @echo "Writing shortcut script go-benchmark..." @echo '#! /bin/sh' > go-benchmark @echo 'mkdir tmp_cc && mv *.cc tmp_cc' >> go-benchmark - @echo 'for file in $$@; do' >> go-benchmark - @echo ' echo "Testing go benchmark for data file: $$file";' >> go-benchmark - @echo ' go test -bench=. -- $$file;' >> go-benchmark - @echo 'done' >> go-benchmark + @echo 'go test -bench=. -- $$@' >> go-benchmark @echo 'mv tmp_cc/* . && rm -rf tmp_cc' >> go-benchmark @chmod +x go-benchmark diff --git a/benchmarks/go_benchmark_test.go b/benchmarks/go_benchmark_test.go index 59d5856b..c8a70280 100644 --- a/benchmarks/go_benchmark_test.go +++ b/benchmarks/go_benchmark_test.go @@ -7,127 +7,117 @@ import ( googleMessage2 "./tmp/datasets/google_message2" googleMessage3 "./tmp/datasets/google_message3" googleMessage4 "./tmp/datasets/google_message4" - "errors" "flag" "github.com/golang/protobuf/proto" "io/ioutil" - "os" "testing" ) // Data is returned by the Load function. -type Data struct { - // marshaled is a slice of marshaled protocol - // buffers. 1:1 with unmarshaled. - marshaled [][]byte - - // Unmarshaled is a slice of unmarshaled protocol - // buffers. 1:1 with marshaled. +type Dataset struct { + name string + newMessage func() proto.Message + marshaled [][]byte unmarshaled []proto.Message - - count int } -var data *Data -var counter int - -type GetDefaultInstanceFunction func() proto.Message - -var getDefaultInstance GetDefaultInstanceFunction +var datasets []Dataset // This is used to getDefaultInstance for a message type. -func generateGetDefaltInstanceFunction(dataset benchmarkWrapper.BenchmarkDataset) error { +func generateNewMessageFunction(dataset benchmarkWrapper.BenchmarkDataset) func() proto.Message { switch dataset.MessageName { case "benchmarks.proto3.GoogleMessage1": - getDefaultInstance = func() proto.Message { return &googleMessage1Proto3.GoogleMessage1{} } - return nil + return func() proto.Message { return new(googleMessage1Proto3.GoogleMessage1) } case "benchmarks.proto2.GoogleMessage1": - getDefaultInstance = func() proto.Message { return &googleMessage1Proto2.GoogleMessage1{} } - return nil + return func() proto.Message { return new(googleMessage1Proto2.GoogleMessage1) } case "benchmarks.proto2.GoogleMessage2": - getDefaultInstance = func() proto.Message { return &googleMessage2.GoogleMessage2{} } - return nil + return func() proto.Message { return new(googleMessage2.GoogleMessage2) } case "benchmarks.google_message3.GoogleMessage3": - getDefaultInstance = func() proto.Message { return &googleMessage3.GoogleMessage3{} } - return nil + return func() proto.Message { return new(googleMessage3.GoogleMessage3) } case "benchmarks.google_message4.GoogleMessage4": - getDefaultInstance = func() proto.Message { return &googleMessage4.GoogleMessage4{} } - return nil + return func() proto.Message { return new(googleMessage4.GoogleMessage4) } default: - return errors.New("Unknown message type: " + dataset.MessageName) + panic("Unknown message type: " + dataset.MessageName) } } -func TestMain(m *testing.M) { +func init() { flag.Parse() - data = new(Data) - rawData, err := ioutil.ReadFile(flag.Arg(0)) - if err != nil { - panic("Couldn't find file" + flag.Arg(0)) - } - var dataset benchmarkWrapper.BenchmarkDataset - - if err = proto.Unmarshal(rawData, &dataset); err != nil { - panic("The raw input data can't be parse into BenchmarkDataset message.") - } - - generateGetDefaltInstanceFunction(dataset) - - for _, payload := range dataset.Payload { - data.marshaled = append(data.marshaled, payload) - m := getDefaultInstance() - proto.Unmarshal(payload, m) - data.unmarshaled = append(data.unmarshaled, m) - } - data.count = len(data.unmarshaled) - - os.Exit(m.Run()) -} - -func BenchmarkUnmarshal(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - payload := data.marshaled[counter%data.count] - out := getDefaultInstance() - if err := proto.Unmarshal(payload, out); err != nil { - b.Fatalf("can't unmarshal message %d %v", counter%data.count, err) + for _, f := range flag.Args() { + // Load the benchmark. + b, err := ioutil.ReadFile(f) + if err != nil { + panic(err) } - counter++ - } -} -func BenchmarkMarshal(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - m := data.unmarshaled[counter%data.count] - if _, err := proto.Marshal(m); err != nil { - b.Fatalf("can't marshal message %d %+v: %v", counter%data.count, m, err) + // Parse the benchmark. + var dm benchmarkWrapper.BenchmarkDataset + if err := proto.Unmarshal(b, &dm); err != nil { + panic(err) } - counter++ - } -} -func BenchmarkSize(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - proto.Size(data.unmarshaled[counter%data.count]) - counter++ - } -} + // Determine the concrete protobuf message type to use. + var ds Dataset + ds.newMessage = generateNewMessageFunction(dm) + + // Unmarshal each test message. + for _, payload := range dm.Payload { + ds.marshaled = append(ds.marshaled, payload) + m := ds.newMessage() + if err := proto.Unmarshal(payload, m); err != nil { + panic(err) + } + ds.unmarshaled = append(ds.unmarshaled, m) + } + ds.name = f -func BenchmarkClone(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - proto.Clone(data.unmarshaled[counter%data.count]) - counter++ + datasets = append(datasets, ds) } } -func BenchmarkMerge(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - out := getDefaultInstance() - proto.Merge(out, data.unmarshaled[counter%data.count]) - counter++ +func Benchmark(b *testing.B) { + for _, ds := range datasets { + b.Run(ds.name, func(b *testing.B) { + counter := 0 + count := len(ds.marshaled) + b.Run("Unmarshal", func(b *testing.B) { + for i := 0; i < b.N; i++ { + payload := ds.marshaled[counter%count] + out := ds.newMessage() + if err := proto.Unmarshal(payload, out); err != nil { + b.Fatalf("can't unmarshal message %d %v", counter%count, err) + } + counter++ + } + }) + b.Run("Marshal", func(b *testing.B) { + for i := 0; i < b.N; i++ { + m := ds.unmarshaled[counter%count] + if _, err := proto.Marshal(m); err != nil { + b.Fatalf("can't marshal message %d %+v: %v", counter%count, m, err) + } + counter++ + } + }) + b.Run("Size", func(b *testing.B) { + for i := 0; i < b.N; i++ { + proto.Size(ds.unmarshaled[counter%count]) + counter++ + } + }) + b.Run("Clone", func(b *testing.B) { + for i := 0; i < b.N; i++ { + proto.Clone(ds.unmarshaled[counter%count]) + counter++ + } + }) + b.Run("Merge", func(b *testing.B) { + for i := 0; i < b.N; i++ { + out := ds.newMessage() + proto.Merge(out, ds.unmarshaled[counter%count]) + counter++ + } + }) + }) } } -- cgit v1.2.3 From d6323c8c0f029d4ce3324fcaa635f08139196e0d Mon Sep 17 00:00:00 2001 From: Yilun Chong Date: Mon, 19 Mar 2018 16:43:27 -0700 Subject: Change to deal all messages in one loop --- benchmarks/go_benchmark_test.go | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'benchmarks') diff --git a/benchmarks/go_benchmark_test.go b/benchmarks/go_benchmark_test.go index c8a70280..e747465e 100644 --- a/benchmarks/go_benchmark_test.go +++ b/benchmarks/go_benchmark_test.go @@ -78,44 +78,45 @@ func init() { func Benchmark(b *testing.B) { for _, ds := range datasets { b.Run(ds.name, func(b *testing.B) { - counter := 0 - count := len(ds.marshaled) b.Run("Unmarshal", func(b *testing.B) { for i := 0; i < b.N; i++ { - payload := ds.marshaled[counter%count] - out := ds.newMessage() - if err := proto.Unmarshal(payload, out); err != nil { - b.Fatalf("can't unmarshal message %d %v", counter%count, err) + for j, payload := range ds.marshaled { + out := ds.newMessage() + if err := proto.Unmarshal(payload, out); err != nil { + b.Fatalf("can't unmarshal message %d %v", j, err) + } } - counter++ } }) b.Run("Marshal", func(b *testing.B) { for i := 0; i < b.N; i++ { - m := ds.unmarshaled[counter%count] - if _, err := proto.Marshal(m); err != nil { - b.Fatalf("can't marshal message %d %+v: %v", counter%count, m, err) + for j, m := range ds.unmarshaled { + if _, err := proto.Marshal(m); err != nil { + b.Fatalf("can't marshal message %d %+v: %v", j, m, err) + } } - counter++ } }) b.Run("Size", func(b *testing.B) { for i := 0; i < b.N; i++ { - proto.Size(ds.unmarshaled[counter%count]) - counter++ + for _, m := range ds.unmarshaled { + proto.Size(m) + } } }) b.Run("Clone", func(b *testing.B) { for i := 0; i < b.N; i++ { - proto.Clone(ds.unmarshaled[counter%count]) - counter++ + for _, m := range ds.unmarshaled { + proto.Clone(m) + } } }) b.Run("Merge", func(b *testing.B) { for i := 0; i < b.N; i++ { - out := ds.newMessage() - proto.Merge(out, ds.unmarshaled[counter%count]) - counter++ + for _, m := range ds.unmarshaled { + out := ds.newMessage() + proto.Merge(out, m) + } } }) }) -- cgit v1.2.3