aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/protobuf/3.4.0/benchmarks
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/protobuf/3.4.0/benchmarks')
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/Makefile.am78
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/ProtoBench.java203
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/README.md28
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/benchmark_messages_proto2.proto143
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/benchmark_messages_proto3.proto78
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/benchmarks.proto63
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/cpp_benchmark.cc242
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/generate_datasets.cc117
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/google_message1.datbin0 -> 228 bytes
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/google_message2.datbin0 -> 84570 bytes
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/google_size.proto138
-rw-r--r--third_party/protobuf/3.4.0/benchmarks/readme.txt46
12 files changed, 1136 insertions, 0 deletions
diff --git a/third_party/protobuf/3.4.0/benchmarks/Makefile.am b/third_party/protobuf/3.4.0/benchmarks/Makefile.am
new file mode 100644
index 0000000000..d98eae5ead
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/Makefile.am
@@ -0,0 +1,78 @@
+
+benchmarks_protoc_inputs = \
+ benchmarks.proto \
+ benchmark_messages_proto3.proto
+
+benchmarks_protoc_inputs_proto2 = \
+ benchmark_messages_proto2.proto
+
+benchmarks_protoc_outputs = \
+ benchmarks.pb.cc \
+ benchmarks.pb.h \
+ benchmark_messages_proto3.pb.cc \
+ benchmark_messages_proto3.pb.h
+
+benchmarks_protoc_outputs_proto2 = \
+ benchmark_messages_proto2.pb.cc \
+ benchmark_messages_proto2.pb.h
+
+AM_CXXFLAGS = $(NO_OPT_CXXFLAGS) $(PROTOBUF_OPT_FLAG) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+
+bin_PROGRAMS = generate-datasets cpp-benchmark
+
+generate_datasets_LDADD = $(top_srcdir)/src/libprotobuf.la
+generate_datasets_SOURCES = generate_datasets.cc
+generate_datasets_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)
+nodist_generate_datasets_SOURCES = \
+ $(benchmarks_protoc_outputs) \
+ $(benchmarks_protoc_outputs_proto2)
+
+# Explicit deps because BUILT_SOURCES are only done before a "make all/check"
+# so a direct "make test_cpp" could fail if parallel enough.
+# See: https://www.gnu.org/software/automake/manual/html_node/Built-Sources-Example.html#Recording-Dependencies-manually
+generate_datasets-generate_datasets.$(OBJEXT): benchmarks.pb.h
+
+cpp_benchmark_LDADD = $(top_srcdir)/src/libprotobuf.la $(top_srcdir)/third_party/benchmark/src/libbenchmark.a
+cpp_benchmark_SOURCES = cpp_benchmark.cc
+cpp_benchmark_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir) -I$(top_srcdir)/third_party/benchmark/include
+nodist_cpp_benchmark_SOURCES = \
+ $(benchmarks_protoc_outputs) \
+ $(benchmarks_protoc_outputs_proto2)
+
+$(benchmarks_protoc_outputs): protoc_middleman
+$(benchmarks_protoc_outputs_proto2): protoc_middleman2
+
+CLEANFILES = \
+ $(benchmarks_protoc_outputs) \
+ $(benchmarks_protoc_outputs_proto2) \
+ protoc_middleman \
+ protoc_middleman2 \
+ dataset.*
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
+
+if USE_EXTERNAL_PROTOC
+
+protoc_middleman: $(benchmarks_protoc_inputs)
+ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. $(benchmarks_protoc_inputs)
+ touch protoc_middleman
+
+protoc_middleman2: $(benchmarks_protoc_inputs_proto2)
+ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. $(benchmarks_protoc_inputs_proto2)
+ 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.
+protoc_middleman: $(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 $(benchmarks_protoc_inputs) )
+ touch protoc_middleman
+
+protoc_middleman2: $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs_proto2) $(well_known_type_protoc_inputs)
+ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd $(benchmarks_protoc_inputs_proto2) )
+ touch protoc_middleman
+
+endif
diff --git a/third_party/protobuf/3.4.0/benchmarks/ProtoBench.java b/third_party/protobuf/3.4.0/benchmarks/ProtoBench.java
new file mode 100644
index 0000000000..86d62feb67
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/ProtoBench.java
@@ -0,0 +1,203 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2009 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protocolbuffers;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Method;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.CodedInputStream;
+import com.google.protobuf.CodedOutputStream;
+import com.google.protobuf.Message;
+
+public class ProtoBench {
+
+ private static final long MIN_SAMPLE_TIME_MS = 2 * 1000;
+ private static final long TARGET_TIME_MS = 30 * 1000;
+
+ private ProtoBench() {
+ // Prevent instantiation
+ }
+
+ public static void main(String[] args) {
+ if (args.length < 2 || (args.length % 2) != 0) {
+ System.err.println("Usage: ProtoBench <descriptor type name> <input data>");
+ System.err.println("The descriptor type name is the fully-qualified message name,");
+ System.err.println("e.g. com.google.protocolbuffers.benchmark.Message1");
+ System.err.println("(You can specify multiple pairs of descriptor type name and input data.)");
+ System.exit(1);
+ }
+ boolean success = true;
+ for (int i = 0; i < args.length; i += 2) {
+ success &= runTest(args[i], args[i + 1]);
+ }
+ System.exit(success ? 0 : 1);
+ }
+
+ /**
+ * Runs a single test. Error messages are displayed to stderr, and the return value
+ * indicates general success/failure.
+ */
+ public static boolean runTest(String type, String file) {
+ System.out.println("Benchmarking " + type + " with file " + file);
+ final Message defaultMessage;
+ try {
+ Class<?> clazz = Class.forName(type);
+ Method method = clazz.getDeclaredMethod("getDefaultInstance");
+ defaultMessage = (Message) method.invoke(null);
+ } catch (Exception e) {
+ // We want to do the same thing with all exceptions. Not generally nice,
+ // but this is slightly different.
+ System.err.println("Unable to get default message for " + type);
+ return false;
+ }
+
+ try {
+ final byte[] inputData = readAllBytes(file);
+ final ByteArrayInputStream inputStream = new ByteArrayInputStream(inputData);
+ final ByteString inputString = ByteString.copyFrom(inputData);
+ final Message sampleMessage = defaultMessage.newBuilderForType().mergeFrom(inputString).build();
+ FileOutputStream devNullTemp = null;
+ CodedOutputStream reuseDevNullTemp = null;
+ try {
+ devNullTemp = new FileOutputStream("/dev/null");
+ reuseDevNullTemp = CodedOutputStream.newInstance(devNullTemp);
+ } catch (FileNotFoundException e) {
+ // ignore: this is probably Windows, where /dev/null does not exist
+ }
+ final FileOutputStream devNull = devNullTemp;
+ final CodedOutputStream reuseDevNull = reuseDevNullTemp;
+ benchmark("Serialize to byte string", inputData.length, new Action() {
+ public void execute() { sampleMessage.toByteString(); }
+ });
+ benchmark("Serialize to byte array", inputData.length, new Action() {
+ public void execute() { sampleMessage.toByteArray(); }
+ });
+ benchmark("Serialize to memory stream", inputData.length, new Action() {
+ public void execute() throws IOException {
+ sampleMessage.writeTo(new ByteArrayOutputStream());
+ }
+ });
+ if (devNull != null) {
+ benchmark("Serialize to /dev/null with FileOutputStream", inputData.length, new Action() {
+ public void execute() throws IOException {
+ sampleMessage.writeTo(devNull);
+ }
+ });
+ benchmark("Serialize to /dev/null reusing FileOutputStream", inputData.length, new Action() {
+ public void execute() throws IOException {
+ sampleMessage.writeTo(reuseDevNull);
+ reuseDevNull.flush(); // force the write to the OutputStream
+ }
+ });
+ }
+ benchmark("Deserialize from byte string", inputData.length, new Action() {
+ public void execute() throws IOException {
+ defaultMessage.newBuilderForType().mergeFrom(inputString).build();
+ }
+ });
+ benchmark("Deserialize from byte array", inputData.length, new Action() {
+ public void execute() throws IOException {
+ defaultMessage.newBuilderForType()
+ .mergeFrom(CodedInputStream.newInstance(inputData)).build();
+ }
+ });
+ benchmark("Deserialize from memory stream", inputData.length, new Action() {
+ public void execute() throws IOException {
+ defaultMessage.newBuilderForType()
+ .mergeFrom(CodedInputStream.newInstance(inputStream)).build();
+ inputStream.reset();
+ }
+ });
+ System.out.println();
+ return true;
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ System.err.println("Detailed exception information:");
+ e.printStackTrace(System.err);
+ return false;
+ }
+ }
+
+ private static void benchmark(String name, long dataSize, Action action) throws IOException {
+ // Make sure it's JITted "reasonably" hard before running the first progress test
+ for (int i=0; i < 100; i++) {
+ action.execute();
+ }
+
+ // Run it progressively more times until we've got a reasonable sample
+ int iterations = 1;
+ long elapsed = timeAction(action, iterations);
+ while (elapsed < MIN_SAMPLE_TIME_MS) {
+ iterations *= 2;
+ elapsed = timeAction(action, iterations);
+ }
+
+ // Upscale the sample to the target time. Do this in floating point arithmetic
+ // to avoid overflow issues.
+ iterations = (int) ((TARGET_TIME_MS / (double) elapsed) * iterations);
+ elapsed = timeAction(action, iterations);
+ System.out.println(name + ": " + iterations + " iterations in "
+ + (elapsed/1000f) + "s; "
+ + (iterations * dataSize) / (elapsed * 1024 * 1024 / 1000f)
+ + "MB/s");
+ }
+
+ private static long timeAction(Action action, int iterations) throws IOException {
+ System.gc();
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < iterations; i++) {
+ action.execute();
+ }
+ long end = System.currentTimeMillis();
+ return end - start;
+ }
+
+ private static byte[] readAllBytes(String filename) throws IOException {
+ RandomAccessFile file = new RandomAccessFile(new File(filename), "r");
+ byte[] content = new byte[(int) file.length()];
+ file.readFully(content);
+ return content;
+ }
+
+ /**
+ * Interface used to capture a single action to benchmark.
+ */
+ interface Action {
+ void execute() throws IOException;
+ }
+}
diff --git a/third_party/protobuf/3.4.0/benchmarks/README.md b/third_party/protobuf/3.4.0/benchmarks/README.md
new file mode 100644
index 0000000000..c902780582
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/README.md
@@ -0,0 +1,28 @@
+
+# Protocol Buffers Benchmarks
+
+This directory contains benchmarking schemas and data sets that you
+can use to test a variety of performance scenarios against your
+protobuf language runtime.
+
+The schema for the datasets is described in `benchmarks.proto`.
+
+Generate the data sets like so:
+
+```
+$ make
+$ ./generate-datasets
+Wrote dataset: dataset.google_message1_proto3.pb
+Wrote dataset: dataset.google_message1_proto2.pb
+Wrote dataset: dataset.google_message2.pb
+$
+```
+
+Each data set will be written to its own file. Benchmarks will
+likely want to run several benchmarks against each data set (parse,
+serialize, possibly JSON, possibly using different APIs, etc).
+
+We would like to add more data sets. In general we will favor data sets
+that make the overall suite diverse without being too large or having
+too many similar tests. Ideally everyone can run through the entire
+suite without the test run getting too long.
diff --git a/third_party/protobuf/3.4.0/benchmarks/benchmark_messages_proto2.proto b/third_party/protobuf/3.4.0/benchmarks/benchmark_messages_proto2.proto
new file mode 100644
index 0000000000..590855033c
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/benchmark_messages_proto2.proto
@@ -0,0 +1,143 @@
+// 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;
+}
+
+message GoogleMessage2 {
+ optional string field1 = 1;
+ optional int64 field3 = 3;
+ optional int64 field4 = 4;
+ optional int64 field30 = 30;
+ optional bool field75 = 75 [default=false];
+ optional string field6 = 6;
+ optional bytes field2 = 2;
+ optional int32 field21 = 21 [default=0];
+ optional int32 field71 = 71;
+ optional float field25 = 25;
+ optional int32 field109 = 109 [default=0];
+ optional int32 field210 = 210 [default=0];
+ optional int32 field211 = 211 [default=0];
+ optional int32 field212 = 212 [default=0];
+ optional int32 field213 = 213 [default=0];
+ optional int32 field216 = 216 [default=0];
+ optional int32 field217 = 217 [default=0];
+ optional int32 field218 = 218 [default=0];
+ optional int32 field220 = 220 [default=0];
+ optional int32 field221 = 221 [default=0];
+ optional float field222 = 222 [default=0.0];
+ optional int32 field63 = 63;
+
+ repeated group Group1 = 10 {
+ required float field11 = 11;
+ optional float field26 = 26;
+ optional string field12 = 12;
+ optional string field13 = 13;
+ repeated string field14 = 14;
+ required uint64 field15 = 15;
+ optional int32 field5 = 5;
+ optional string field27 = 27;
+ optional int32 field28 = 28;
+ optional string field29 = 29;
+ optional string field16 = 16;
+ repeated string field22 = 22;
+ repeated int32 field73 = 73;
+ optional int32 field20 = 20 [default=0];
+ optional string field24 = 24;
+ optional GoogleMessage2GroupedMessage field31 = 31;
+ }
+ repeated string field128 = 128;
+ optional int64 field131 = 131;
+ repeated string field127 = 127;
+ optional int32 field129 = 129;
+ repeated int64 field130 = 130;
+ optional bool field205 = 205 [default=false];
+ optional bool field206 = 206 [default=false];
+}
+
+message GoogleMessage2GroupedMessage {
+ optional float field1 = 1;
+ optional float field2 = 2;
+ optional float field3 = 3 [default=0.0];
+ optional bool field4 = 4;
+ optional bool field5 = 5;
+ optional bool field6 = 6 [default=true];
+ optional bool field7 = 7 [default=false];
+ optional float field8 = 8;
+ optional bool field9 = 9;
+ optional float field10 = 10;
+ optional int64 field11 = 11;
+}
diff --git a/third_party/protobuf/3.4.0/benchmarks/benchmark_messages_proto3.proto b/third_party/protobuf/3.4.0/benchmarks/benchmark_messages_proto3.proto
new file mode 100644
index 0000000000..090b554be9
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/benchmark_messages_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/third_party/protobuf/3.4.0/benchmarks/benchmarks.proto b/third_party/protobuf/3.4.0/benchmarks/benchmarks.proto
new file mode 100644
index 0000000000..51c0b54877
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/benchmarks.proto
@@ -0,0 +1,63 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+package benchmarks;
+option java_package = "com.google.protobuf.benchmarks";
+
+message BenchmarkDataset {
+ // Name of the benchmark dataset. This should be unique across all datasets.
+ // Should only contain word characters: [a-zA-Z0-9_]
+ string name = 1;
+
+ // Fully-qualified name of the protobuf message for this dataset.
+ // It will be one of the messages defined benchmark_messages_proto2.proto
+ // or benchmark_messages_proto3.proto.
+ //
+ // Implementations that do not support reflection can implement this with
+ // an explicit "if/else" chain that lists every known message defined
+ // in those files.
+ string message_name = 2;
+
+ // The payload(s) for this dataset. They should be parsed or serialized
+ // in sequence, in a loop, ie.
+ //
+ // while (!benchmarkDone) { // Benchmark runner decides when to exit.
+ // for (i = 0; i < benchmark.payload.length; i++) {
+ // parse(benchmark.payload[i])
+ // }
+ // }
+ //
+ // This is intended to let datasets include a variety of data to provide
+ // potentially more realistic results than just parsing the same message
+ // over and over. A single message parsed repeatedly could yield unusually
+ // good branch prediction performance.
+ repeated bytes payload = 3;
+}
diff --git a/third_party/protobuf/3.4.0/benchmarks/cpp_benchmark.cc b/third_party/protobuf/3.4.0/benchmarks/cpp_benchmark.cc
new file mode 100644
index 0000000000..0e6febc2f1
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/cpp_benchmark.cc
@@ -0,0 +1,242 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <glob.h>
+#include <iostream>
+#include <fstream>
+#include "benchmark/benchmark_api.h"
+#include "benchmarks.pb.h"
+#include "benchmark_messages_proto2.pb.h"
+#include "benchmark_messages_proto3.pb.h"
+
+#define PREFIX "dataset."
+#define SUFFIX ".pb"
+
+using benchmarks::BenchmarkDataset;
+using google::protobuf::Arena;
+using google::protobuf::Descriptor;
+using google::protobuf::DescriptorPool;
+using google::protobuf::Message;
+using google::protobuf::MessageFactory;
+
+class Fixture : public benchmark::Fixture {
+ public:
+ Fixture(const BenchmarkDataset& dataset, const std::string& suffix) {
+ for (int i = 0; i < dataset.payload_size(); i++) {
+ payloads_.push_back(dataset.payload(i));
+ }
+
+ const Descriptor* d =
+ DescriptorPool::generated_pool()->FindMessageTypeByName(
+ dataset.message_name());
+
+ if (!d) {
+ std::cerr << "Couldn't find message named '" << dataset.message_name()
+ << "\n";
+ }
+
+ prototype_ = MessageFactory::generated_factory()->GetPrototype(d);
+ SetName((dataset.name() + suffix).c_str());
+ }
+
+ protected:
+ std::vector<std::string> payloads_;
+ const Message* prototype_;
+};
+
+class WrappingCounter {
+ public:
+ WrappingCounter(size_t limit) : value_(0), limit_(limit) {}
+
+ size_t Next() {
+ size_t ret = value_;
+ if (++value_ == limit_) {
+ value_ = 0;
+ }
+ return ret;
+ }
+
+ private:
+ size_t value_;
+ size_t limit_;
+};
+
+template <class T>
+class ParseNewFixture : public Fixture {
+ public:
+ ParseNewFixture(const BenchmarkDataset& dataset)
+ : Fixture(dataset, "_parse_new") {}
+
+ virtual void BenchmarkCase(benchmark::State& state) {
+ WrappingCounter i(payloads_.size());
+ size_t total = 0;
+
+ while (state.KeepRunning()) {
+ T m;
+ const std::string& payload = payloads_[i.Next()];
+ total += payload.size();
+ m.ParseFromString(payload);
+ }
+
+ state.SetBytesProcessed(total);
+ }
+};
+
+template <class T>
+class ParseNewArenaFixture : public Fixture {
+ public:
+ ParseNewArenaFixture(const BenchmarkDataset& dataset)
+ : Fixture(dataset, "_parse_newarena") {}
+
+ virtual void BenchmarkCase(benchmark::State& state) {
+ WrappingCounter i(payloads_.size());
+ size_t total = 0;
+
+ while (state.KeepRunning()) {
+ Arena arena;
+ Message* m = Arena::CreateMessage<T>(&arena);
+ const std::string& payload = payloads_[i.Next()];
+ total += payload.size();
+ m->ParseFromString(payload);
+ }
+
+ state.SetBytesProcessed(total);
+ }
+};
+
+template <class T>
+class ParseReuseFixture : public Fixture {
+ public:
+ ParseReuseFixture(const BenchmarkDataset& dataset)
+ : Fixture(dataset, "_parse_reuse") {}
+
+ virtual void BenchmarkCase(benchmark::State& state) {
+ T m;
+ WrappingCounter i(payloads_.size());
+ size_t total = 0;
+
+ while (state.KeepRunning()) {
+ const std::string& payload = payloads_[i.Next()];
+ total += payload.size();
+ m.ParseFromString(payload);
+ }
+
+ state.SetBytesProcessed(total);
+ }
+};
+
+template <class T>
+class SerializeFixture : public Fixture {
+ public:
+ SerializeFixture(const BenchmarkDataset& dataset)
+ : Fixture(dataset, "_serialize") {
+ for (size_t i = 0; i < payloads_.size(); i++) {
+ message_.push_back(new T);
+ message_.back()->ParseFromString(payloads_[i]);
+ }
+ }
+
+ ~SerializeFixture() {
+ for (size_t i = 0; i < message_.size(); i++) {
+ delete message_[i];
+ }
+ }
+
+ virtual void BenchmarkCase(benchmark::State& state) {
+ size_t total = 0;
+ std::string str;
+ WrappingCounter i(payloads_.size());
+
+ while (state.KeepRunning()) {
+ str.clear();
+ message_[i.Next()]->SerializeToString(&str);
+ total += str.size();
+ }
+
+ state.SetBytesProcessed(total);
+ }
+
+ private:
+ std::vector<T*> message_;
+};
+
+std::string ReadFile(const std::string& name) {
+ std::ifstream file(name.c_str());
+ GOOGLE_CHECK(file.is_open()) << "Couldn't find file '" << name <<
+ "', please make sure you are running "
+ "this command from the benchmarks/ "
+ "directory.\n";
+ return std::string((std::istreambuf_iterator<char>(file)),
+ std::istreambuf_iterator<char>());
+}
+
+template <class T>
+void RegisterBenchmarksForType(const BenchmarkDataset& dataset) {
+ ::benchmark::internal::RegisterBenchmarkInternal(
+ new ParseNewFixture<T>(dataset));
+ ::benchmark::internal::RegisterBenchmarkInternal(
+ new ParseReuseFixture<T>(dataset));
+ ::benchmark::internal::RegisterBenchmarkInternal(
+ new ParseNewArenaFixture<T>(dataset));
+ ::benchmark::internal::RegisterBenchmarkInternal(
+ new SerializeFixture<T>(dataset));
+}
+
+void RegisterBenchmarks(const std::string& dataset_bytes) {
+ BenchmarkDataset dataset;
+ GOOGLE_CHECK(dataset.ParseFromString(dataset_bytes));
+
+ if (dataset.message_name() == "benchmarks.proto3.GoogleMessage1") {
+ RegisterBenchmarksForType<benchmarks::proto3::GoogleMessage1>(dataset);
+ } else if (dataset.message_name() == "benchmarks.proto2.GoogleMessage1") {
+ RegisterBenchmarksForType<benchmarks::proto2::GoogleMessage1>(dataset);
+ } else if (dataset.message_name() == "benchmarks.proto2.GoogleMessage2") {
+ RegisterBenchmarksForType<benchmarks::proto2::GoogleMessage2>(dataset);
+ } else {
+ std::cerr << "Unknown message type: " << dataset.message_name();
+ exit(1);
+ }
+}
+
+int main(int argc, char *argv[]) {
+ glob_t glob_result;
+ if (glob("dataset.*.pb", 0, NULL, &glob_result) != 0) {
+ fprintf(stderr, "No dataset files found.\n");
+ return 1;
+ }
+
+ for (size_t i = 0; i < glob_result.gl_pathc; i++) {
+ fprintf(stderr, "Found input dataset: %s\n", glob_result.gl_pathv[i]);
+ RegisterBenchmarks(ReadFile(glob_result.gl_pathv[i]));
+ }
+
+ ::benchmark::Initialize(&argc, argv);
+ ::benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/third_party/protobuf/3.4.0/benchmarks/generate_datasets.cc b/third_party/protobuf/3.4.0/benchmarks/generate_datasets.cc
new file mode 100644
index 0000000000..61e7adf1ba
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/generate_datasets.cc
@@ -0,0 +1,117 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <fstream>
+#include <iostream>
+#include "benchmarks.pb.h"
+
+using benchmarks::BenchmarkDataset;
+using google::protobuf::Descriptor;
+using google::protobuf::DescriptorPool;
+using google::protobuf::Message;
+using google::protobuf::MessageFactory;
+
+std::set<std::string> names;
+
+const char *file_prefix = "dataset.";
+const char *file_suffix = ".pb";
+
+void WriteFileWithPayloads(const std::string& name,
+ const std::string& message_name,
+ const std::vector<std::string>& payload) {
+ if (!names.insert(name).second) {
+ std::cerr << "Duplicate test name: " << name << "\n";
+ abort();
+ }
+
+ // First verify that this message name exists in our set of benchmark messages
+ // and that these payloads are valid for the given message.
+ const Descriptor* d =
+ DescriptorPool::generated_pool()->FindMessageTypeByName(message_name);
+
+ if (!d) {
+ std::cerr << "For dataset " << name << ", no such message: "
+ << message_name << "\n";
+ abort();
+ }
+
+ Message* m = MessageFactory::generated_factory()->GetPrototype(d)->New();
+
+ for (size_t i = 0; i < payload.size(); i++) {
+ if (!m->ParseFromString(payload[i])) {
+ std::cerr << "For dataset " << name << ", payload[" << i << "] fails "
+ << "to parse\n";
+ abort();
+ }
+ }
+
+ BenchmarkDataset dataset;
+ dataset.set_name(name);
+ dataset.set_message_name(message_name);
+ for (size_t i = 0; i < payload.size(); i++) {
+ dataset.add_payload()->assign(payload[i]);
+ }
+
+ std::ofstream writer;
+ std::string fname = file_prefix + name + file_suffix;
+ writer.open(fname.c_str());
+ dataset.SerializeToOstream(&writer);
+ writer.close();
+
+ std::cerr << "Wrote dataset: " << fname << "\n";
+}
+
+void WriteFile(const std::string& name, const std::string& message_name,
+ const std::string& payload) {
+ std::vector<std::string> payloads;
+ payloads.push_back(payload);
+ WriteFileWithPayloads(name, message_name, payloads);
+}
+
+std::string ReadFile(const std::string& name) {
+ std::ifstream file(name.c_str());
+ GOOGLE_CHECK(file.is_open()) << "Couldn't find file '" << name <<
+ "', please make sure you are running "
+ "this command from the benchmarks/ "
+ "directory.\n";
+ return std::string((std::istreambuf_iterator<char>(file)),
+ std::istreambuf_iterator<char>());
+}
+
+int main() {
+ WriteFile("google_message1_proto3", "benchmarks.proto3.GoogleMessage1",
+ ReadFile("google_message1.dat"));
+ WriteFile("google_message1_proto2", "benchmarks.proto2.GoogleMessage1",
+ ReadFile("google_message1.dat"));
+
+ // Not in proto3 because it has a group, which is not supported.
+ WriteFile("google_message2", "benchmarks.proto2.GoogleMessage2",
+ ReadFile("google_message2.dat"));
+}
diff --git a/third_party/protobuf/3.4.0/benchmarks/google_message1.dat b/third_party/protobuf/3.4.0/benchmarks/google_message1.dat
new file mode 100644
index 0000000000..bc0f064cc2
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/google_message1.dat
Binary files differ
diff --git a/third_party/protobuf/3.4.0/benchmarks/google_message2.dat b/third_party/protobuf/3.4.0/benchmarks/google_message2.dat
new file mode 100644
index 0000000000..06c09441b9
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/google_message2.dat
Binary files differ
diff --git a/third_party/protobuf/3.4.0/benchmarks/google_size.proto b/third_party/protobuf/3.4.0/benchmarks/google_size.proto
new file mode 100644
index 0000000000..d2d319f31c
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/google_size.proto
@@ -0,0 +1,138 @@
+syntax = "proto2";
+
+package benchmarks;
+
+option java_outer_classname = "GoogleSize";
+option optimize_for = CODE_SIZE;
+
+message SizeMessage1 {
+ 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 SizeMessage1SubMessage 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 SizeMessage1SubMessage {
+ 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;
+}
+
+message SizeMessage2 {
+ optional string field1 = 1;
+ optional int64 field3 = 3;
+ optional int64 field4 = 4;
+ optional int64 field30 = 30;
+ optional bool field75 = 75 [default=false];
+ optional string field6 = 6;
+ optional bytes field2 = 2;
+ optional int32 field21 = 21 [default=0];
+ optional int32 field71 = 71;
+ optional float field25 = 25;
+ optional int32 field109 = 109 [default=0];
+ optional int32 field210 = 210 [default=0];
+ optional int32 field211 = 211 [default=0];
+ optional int32 field212 = 212 [default=0];
+ optional int32 field213 = 213 [default=0];
+ optional int32 field216 = 216 [default=0];
+ optional int32 field217 = 217 [default=0];
+ optional int32 field218 = 218 [default=0];
+ optional int32 field220 = 220 [default=0];
+ optional int32 field221 = 221 [default=0];
+ optional float field222 = 222 [default=0.0];
+ optional int32 field63 = 63;
+
+ repeated group Group1 = 10 {
+ required float field11 = 11;
+ optional float field26 = 26;
+ optional string field12 = 12;
+ optional string field13 = 13;
+ repeated string field14 = 14;
+ required uint64 field15 = 15;
+ optional int32 field5 = 5;
+ optional string field27 = 27;
+ optional int32 field28 = 28;
+ optional string field29 = 29;
+ optional string field16 = 16;
+ repeated string field22 = 22;
+ repeated int32 field73 = 73;
+ optional int32 field20 = 20 [default=0];
+ optional string field24 = 24;
+ optional SizeMessage2GroupedMessage field31 = 31;
+ }
+ repeated string field128 = 128;
+ optional int64 field131 = 131;
+ repeated string field127 = 127;
+ optional int32 field129 = 129;
+ repeated int64 field130 = 130;
+ optional bool field205 = 205 [default=false];
+ optional bool field206 = 206 [default=false];
+}
+
+message SizeMessage2GroupedMessage {
+ optional float field1 = 1;
+ optional float field2 = 2;
+ optional float field3 = 3 [default=0.0];
+ optional bool field4 = 4;
+ optional bool field5 = 5;
+ optional bool field6 = 6 [default=true];
+ optional bool field7 = 7 [default=false];
+ optional float field8 = 8;
+ optional bool field9 = 9;
+ optional float field10 = 10;
+ optional int64 field11 = 11;
+}
diff --git a/third_party/protobuf/3.4.0/benchmarks/readme.txt b/third_party/protobuf/3.4.0/benchmarks/readme.txt
new file mode 100644
index 0000000000..b08b8bc09c
--- /dev/null
+++ b/third_party/protobuf/3.4.0/benchmarks/readme.txt
@@ -0,0 +1,46 @@
+Contents
+--------
+
+This folder contains three kinds of file:
+
+- Code, such as ProtoBench.java, to build the benchmarking framework.
+- Protocol buffer definitions (.proto files)
+- Sample data files
+
+If we end up with a lot of different benchmarks it may be worth
+separating these out info different directories, but while there are
+so few they might as well all be together.
+
+Running a benchmark (Java)
+--------------------------
+
+1) Build protoc and the Java protocol buffer library. The examples
+ below assume a jar file (protobuf.jar) has been built and copied
+ into this directory.
+
+2) Build ProtoBench:
+ $ javac -d tmp -cp protobuf.jar ProtoBench.java
+
+3) Generate code for the relevant benchmark protocol buffer, e.g.
+ $ protoc --java_out=tmp google_size.proto
+
+4) Build the generated code, e.g.
+ $ javac -d tmp -cp protobuf.jar tmp/benchmarks/*.java
+
+5) Run the test. Arguments are given in pairs - the first argument
+ is the descriptor type; the second is the filename. For example:
+ $ java -cp tmp:protobuf.jar com.google.protocolbuffers.ProtoBench \
+ 'benchmarks.GoogleSize$SizeMessage1' google_message1.dat \
+ 'benchmarks.GoogleSize$SizeMessage2' google_message2.dat
+
+6) Wait! Each test runs for around 30 seconds, and there are 8 tests
+ per class/data combination. The above command would therefore take
+ about 8 minutes to run.
+
+
+Benchmarks available
+--------------------
+
+From Google:
+google_size.proto,
+messages google_message1.dat and google_message2.dat.