From a2cbd5a8246e7203b27cb938bc170c29e33269ec Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 6 Apr 2020 16:40:50 +0200 Subject: [PATCH] serialization benchmark improvements --- ...ionConfig.cs => BenchmarkDatasetConfig.cs} | 14 ++++---- ...Benchmark.cs => GoogleMessageBenchmark.cs} | 32 +++++++++++-------- 2 files changed, 25 insertions(+), 21 deletions(-) rename csharp/src/Google.Protobuf.Benchmarks/{SerializationConfig.cs => BenchmarkDatasetConfig.cs} (89%) rename csharp/src/Google.Protobuf.Benchmarks/{SerializationBenchmark.cs => GoogleMessageBenchmark.cs} (74%) diff --git a/csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs similarity index 89% rename from csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs rename to csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs index 679f16cb9a..c0754190b6 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs +++ b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs @@ -43,20 +43,20 @@ namespace Google.Protobuf.Benchmarks /// /// The configuration for a single serialization test, loaded from a dataset. /// - public class SerializationConfig + public class BenchmarkDatasetConfig { private static readonly Dictionary parsersByMessageName = - typeof(SerializationBenchmark).Assembly.GetTypes() + typeof(GoogleMessageBenchmark).Assembly.GetTypes() .Where(t => typeof(IMessage).IsAssignableFrom(t)) .ToDictionary( t => ((MessageDescriptor) t.GetProperty("Descriptor", BindingFlags.Static | BindingFlags.Public).GetValue(null)).FullName, t => ((MessageParser) t.GetProperty("Parser", BindingFlags.Static | BindingFlags.Public).GetValue(null))); public MessageParser Parser { get; } - public IEnumerable Payloads { get; } + public List Payloads { get; } public string Name { get; } - public SerializationConfig(string resource) + public BenchmarkDatasetConfig(string resource, string shortName = null) { var data = LoadData(resource); var dataset = BenchmarkDataset.Parser.ParseFrom(data); @@ -66,13 +66,13 @@ namespace Google.Protobuf.Benchmarks throw new ArgumentException($"No parser for message {dataset.MessageName} in this assembly"); } Parser = parser; - Payloads = dataset.Payload; - Name = dataset.Name; + Payloads = new List(dataset.Payload.Select(p => p.ToByteArray())); + Name = shortName ?? dataset.Name; } private static byte[] LoadData(string resource) { - using (var stream = typeof(SerializationBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}")) + using (var stream = typeof(GoogleMessageBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}")) { if (stream == null) { diff --git a/csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs b/csharp/src/Google.Protobuf.Benchmarks/GoogleMessageBenchmark.cs similarity index 74% rename from csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs rename to csharp/src/Google.Protobuf.Benchmarks/GoogleMessageBenchmark.cs index d8c2ec11d7..132967e00a 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs +++ b/csharp/src/Google.Protobuf.Benchmarks/GoogleMessageBenchmark.cs @@ -38,23 +38,27 @@ using System.Linq; namespace Google.Protobuf.Benchmarks { /// - /// Benchmark for serializing (to a MemoryStream) and deserializing (from a ByteString). + /// Benchmark for serializing and deserializing of standard datasets that are also + /// measured by benchmarks in other languages. /// Over time we may wish to test the various different approaches to serialization and deserialization separately. + /// See https://github.com/protocolbuffers/protobuf/blob/master/benchmarks/README.md + /// See https://github.com/protocolbuffers/protobuf/blob/master/docs/performance.md /// [MemoryDiagnoser] - public class SerializationBenchmark + public class GoogleMessageBenchmark { /// - /// All the configurations to be tested. Add more datasets to the array as they're available. + /// All the datasets to be tested. Add more datasets to the array as they're available. /// (When C# supports proto2, this will increase significantly.) /// - public static SerializationConfig[] Configurations => new[] + public static BenchmarkDatasetConfig[] DatasetConfigurations => new[] { - new SerializationConfig("dataset.google_message1_proto3.pb") + // short name is specified to make results table more readable + new BenchmarkDatasetConfig("dataset.google_message1_proto3.pb", "goog_msg1_proto3") }; - [ParamsSource(nameof(Configurations))] - public SerializationConfig Configuration { get; set; } + [ParamsSource(nameof(DatasetConfigurations))] + public BenchmarkDatasetConfig Dataset { get; set; } private MessageParser parser; /// @@ -67,8 +71,8 @@ namespace Google.Protobuf.Benchmarks [GlobalSetup] public void GlobalSetup() { - parser = Configuration.Parser; - subTests = Configuration.Payloads.Select(p => new SubTest(p, parser.ParseFrom(p))).ToList(); + parser = Dataset.Parser; + subTests = Dataset.Payloads.Select(p => new SubTest(p, parser.ParseFrom(p))).ToList(); } [Benchmark] @@ -78,7 +82,7 @@ namespace Google.Protobuf.Benchmarks public void ToByteArray() => subTests.ForEach(item => item.ToByteArray()); [Benchmark] - public void ParseFromByteString() => subTests.ForEach(item => item.ParseFromByteString(parser)); + public void ParseFromByteArray() => subTests.ForEach(item => item.ParseFromByteArray(parser)); [Benchmark] public void ParseFromStream() => subTests.ForEach(item => item.ParseFromStream(parser)); @@ -87,13 +91,13 @@ namespace Google.Protobuf.Benchmarks { private readonly Stream destinationStream; private readonly Stream sourceStream; - private readonly ByteString data; + private readonly byte[] data; private readonly IMessage message; - public SubTest(ByteString data, IMessage message) + public SubTest(byte[] data, IMessage message) { destinationStream = new MemoryStream(data.Length); - sourceStream = new MemoryStream(data.ToByteArray()); + sourceStream = new MemoryStream(data); this.data = data; this.message = message; } @@ -108,7 +112,7 @@ namespace Google.Protobuf.Benchmarks public void ToByteArray() => message.ToByteArray(); - public void ParseFromByteString(MessageParser parser) => parser.ParseFrom(data); + public void ParseFromByteArray(MessageParser parser) => parser.ParseFrom(data); public void ParseFromStream(MessageParser parser) {