| // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| // ignore_for_file: uri_has_not_been_generated,undefined_class |
| |
| /// Common platform independent benchmark infrastructure that can run |
| /// both on the VM and when compiled to JavaScript. |
| library common; |
| |
| import 'dart:typed_data'; |
| |
| import 'package:benchmark_harness/benchmark_harness.dart'; |
| import 'package:protobuf/protobuf.dart'; |
| |
| import 'temp/benchmarks.pb.dart'; |
| import 'temp/datasets/google_message1/proto2/benchmark_message1_proto2.pb.dart' |
| as p2; |
| import 'temp/datasets/google_message1/proto3/benchmark_message1_proto3.pb.dart' |
| as p3; |
| import 'temp/datasets/google_message2/benchmark_message2.pb.dart'; |
| import 'temp/datasets/google_message3/benchmark_message3.pb.dart'; |
| import 'temp/datasets/google_message4/benchmark_message4.pb.dart'; |
| |
| /// Represents a dataset, a list of protobufs payloads, used for benchmarking. |
| /// All payloads are instances of the same message. |
| /// Datasets are loaded from BenchmarkDataset proto (see benchmark.proto). |
| class Dataset { |
| final String name; |
| |
| /// Functions that can deserialize all payloads in this dataset. |
| final Factories factories; |
| |
| /// List of packed payloads, which can be deserialized using [factories]. |
| /// Used for binary deserialization benchmarks. |
| final List<Uint8List> packed = <Uint8List>[]; |
| |
| /// Messages deserialized from [packed] and then serialized back into JSON. |
| /// Used for JSON serialization benchmarks. |
| final List<String> asJson = <String>[]; |
| |
| /// Messages deserialized from [packed]. Used in serialization benchmarks. |
| final List<GeneratedMessage> unpacked = <GeneratedMessage>[]; |
| |
| /// Create [Dataset] from a [BenchmarkDataset] proto. |
| factory Dataset.fromBinary(List<int> binary) { |
| final dataSet = |
| new BenchmarkDataset.fromBuffer(binary); // ignore: undefined_class |
| |
| final factories = Factories.forMessage(dataSet.messageName); |
| final ds = new Dataset._(dataSet.name, factories); |
| |
| for (var payload in dataSet.payload) { |
| final bytes = new Uint8List.fromList(payload); |
| final msg = factories.fromBuffer(bytes); |
| ds.packed.add(bytes); |
| ds.unpacked.add(msg); |
| ds.asJson.add(msg.writeToJson()); |
| } |
| |
| return ds; |
| } |
| |
| Dataset._(this.name, this.factories); |
| } |
| |
| typedef dynamic FromBufferFactory(List<int> binary); |
| typedef dynamic FromJsonFactory(String json); |
| |
| class Factories { |
| final FromBufferFactory fromBuffer; |
| final FromJsonFactory fromJson; |
| |
| static Factories forMessage(String name) => |
| _factories[name] ?? (throw "Unsupported message: ${name}"); |
| |
| /// Mapping between [BenchmarkProto.messageName] and corresponding |
| /// deserialization factories. |
| static final _factories = { |
| "benchmarks.proto2.GoogleMessage1": new Factories._( |
| fromBuffer: (List<int> binary) => |
| new p2.GoogleMessage1.fromBuffer(binary), |
| fromJson: (String json) => new p2.GoogleMessage1.fromJson(json)), |
| "benchmarks.proto3.GoogleMessage1": new Factories._( |
| fromBuffer: (List<int> binary) => |
| new p3.GoogleMessage1.fromBuffer(binary), |
| fromJson: (String json) => new p3.GoogleMessage1.fromJson(json)), |
| "benchmarks.proto2.GoogleMessage2": new Factories._( |
| fromBuffer: (List<int> binary) => new GoogleMessage2.fromBuffer(binary), |
| fromJson: (String json) => new GoogleMessage2.fromJson(json)), |
| "benchmarks.google_message3.GoogleMessage3": new Factories._( |
| fromBuffer: (List<int> binary) => new GoogleMessage3.fromBuffer(binary), |
| fromJson: (String json) => new GoogleMessage3.fromJson(json)), |
| "benchmarks.google_message4.GoogleMessage4": new Factories._( |
| fromBuffer: (List<int> binary) => new GoogleMessage4.fromBuffer(binary), |
| fromJson: (String json) => new GoogleMessage4.fromJson(json)), |
| }; |
| |
| Factories._({this.fromBuffer, this.fromJson}); |
| } |
| |
| /// Base for all protobuf benchmarks. |
| abstract class _ProtobufBenchmark extends BenchmarkBase { |
| final List<Dataset> datasets; |
| |
| _ProtobufBenchmark(this.datasets, String name) : super(name); |
| } |
| |
| /// Binary deserialization benchmark. |
| class FromBinaryBenchmark extends _ProtobufBenchmark { |
| FromBinaryBenchmark(datasets) : super(datasets, "FromBinary"); |
| |
| void run() { |
| for (var i = 0; i < datasets.length; i++) { |
| final ds = datasets[i]; |
| final f = ds.factories.fromBuffer; |
| for (var j = 0; j < ds.packed.length; j++) { |
| f(ds.packed[j]); |
| } |
| } |
| } |
| } |
| |
| /// Binary serialization benchmark. |
| class ToBinaryBenchmark extends _ProtobufBenchmark { |
| ToBinaryBenchmark(datasets) : super(datasets, "ToBinary"); |
| |
| void run() { |
| for (var i = 0; i < datasets.length; i++) { |
| final ds = datasets[i]; |
| for (var j = 0; j < ds.unpacked.length; j++) { |
| ds.unpacked[j].writeToBuffer(); |
| } |
| } |
| } |
| } |
| |
| /// JSON deserialization benchmark. |
| class FromJsonBenchmark extends _ProtobufBenchmark { |
| FromJsonBenchmark(datasets) : super(datasets, "FromJson"); |
| |
| void run() { |
| for (var i = 0; i < datasets.length; i++) { |
| final ds = datasets[i]; |
| final f = ds.factories.fromJson; |
| for (var j = 0; j < ds.asJson.length; j++) { |
| f(ds.asJson[j]); |
| } |
| } |
| } |
| } |
| |
| /// JSON serialization benchmark. |
| class ToJsonBenchmark extends _ProtobufBenchmark { |
| ToJsonBenchmark(datasets) : super(datasets, "ToJson"); |
| |
| void run() { |
| for (var i = 0; i < datasets.length; i++) { |
| final ds = datasets[i]; |
| for (var j = 0; j < ds.unpacked.length; j++) { |
| ds.unpacked[j].writeToJson(); |
| } |
| } |
| } |
| } |