From 1ac368280fe0196db724ca92eb6d513cc3c4e317 Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Wed, 20 Apr 2022 14:35:34 -0700 Subject: [PATCH] Increased StandardMethodCodec's WriteBuffer start capacity (#101860) * Added standard method codec benchmark * increased writebuffer start size * added const --- .../standard_method_codec_bench.dart | 99 +++++++++++++++++++ dev/devicelab/lib/tasks/microbenchmarks.dart | 1 + .../lib/src/services/message_codecs.dart | 10 +- 3 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 dev/benchmarks/microbenchmarks/lib/foundation/standard_method_codec_bench.dart diff --git a/dev/benchmarks/microbenchmarks/lib/foundation/standard_method_codec_bench.dart b/dev/benchmarks/microbenchmarks/lib/foundation/standard_method_codec_bench.dart new file mode 100644 index 00000000000..2cbb28564ce --- /dev/null +++ b/dev/benchmarks/microbenchmarks/lib/foundation/standard_method_codec_bench.dart @@ -0,0 +1,99 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; + +import '../common.dart'; + +const int _kNumIterations = 100000; + +void main() { + assert(false, + "Don't run benchmarks in checked mode! Use 'flutter run --release'."); + final BenchmarkResultPrinter printer = BenchmarkResultPrinter(); + + const StandardMethodCodec codec = StandardMethodCodec(); + final Stopwatch watch = Stopwatch(); + const String methodName = 'something'; + watch.start(); + for (int i = 0; i < _kNumIterations; i += 1) { + codec.encodeMethodCall(const MethodCall(methodName)); + } + watch.stop(); + + printer.addResult( + description: 'StandardMethodCodec null', + value: watch.elapsedMicroseconds.toDouble() / _kNumIterations, + unit: 'us per iteration', + name: 'StandardMethodCodec_null', + ); + + watch.reset(); + watch.start(); + for (int i = 0; i < _kNumIterations; i += 1) { + codec.encodeMethodCall(const MethodCall(methodName, 12345)); + } + watch.stop(); + + printer.addResult( + description: 'StandardMethodCodec int', + value: watch.elapsedMicroseconds.toDouble() / _kNumIterations, + unit: 'us per iteration', + name: 'StandardMethodCodec_int', + ); + + watch.reset(); + + watch.start(); + for (int i = 0; i < _kNumIterations; i += 1) { + codec.encodeMethodCall( + const MethodCall(methodName, 'This is a performance test.')); + } + watch.stop(); + + printer.addResult( + description: 'StandardMethodCodec string', + value: watch.elapsedMicroseconds.toDouble() / _kNumIterations, + unit: 'us per iteration', + name: 'StandardMethodCodec_string', + ); + + watch.reset(); + watch.start(); + for (int i = 0; i < _kNumIterations; i += 1) { + codec.encodeMethodCall(const MethodCall( + methodName, [1234, 'This is a performance test.', 1.25, true])); + } + watch.stop(); + + printer.addResult( + description: 'StandardMethodCodec heterogenous list', + value: watch.elapsedMicroseconds.toDouble() / _kNumIterations, + unit: 'us per iteration', + name: 'StandardMethodCodec_heterogenous_list', + ); + + watch.reset(); + watch.start(); + for (int i = 0; i < _kNumIterations; i += 1) { + codec.encodeMethodCall(const MethodCall(methodName, { + 'integer': 1234, + 'string': 'This is a performance test.', + 'float': 1.25, + 'boolean': true + })); + } + watch.stop(); + + printer.addResult( + description: 'StandardMethodCodec heterogenous map', + value: watch.elapsedMicroseconds.toDouble() / _kNumIterations, + unit: 'us per iteration', + name: 'StandardMethodCodec_heterogenous_map', + ); + + watch.reset(); + + printer.printToStdout(); +} diff --git a/dev/devicelab/lib/tasks/microbenchmarks.dart b/dev/devicelab/lib/tasks/microbenchmarks.dart index 7006a3bf6d2..0418861923c 100644 --- a/dev/devicelab/lib/tasks/microbenchmarks.dart +++ b/dev/devicelab/lib/tasks/microbenchmarks.dart @@ -61,6 +61,7 @@ TaskFunction createMicrobenchmarkTask() { ...await _runMicrobench('lib/language/sync_star_semantics_bench.dart'), ...await _runMicrobench('lib/foundation/all_elements_bench.dart'), ...await _runMicrobench('lib/foundation/change_notifier_bench.dart'), + ...await _runMicrobench('lib/foundation/standard_method_codec_bench.dart'), ...await _runMicrobench('lib/foundation/standard_message_codec_bench.dart'), ...await _runMicrobench('lib/foundation/timeline_bench.dart'), }; diff --git a/packages/flutter/lib/src/services/message_codecs.dart b/packages/flutter/lib/src/services/message_codecs.dart index d978e0c8754..191a929b359 100644 --- a/packages/flutter/lib/src/services/message_codecs.dart +++ b/packages/flutter/lib/src/services/message_codecs.dart @@ -9,6 +9,8 @@ import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'message_codec.dart'; +const int _writeBufferStartCapacity = 64; + /// [MessageCodec] with unencoded binary messages represented using [ByteData]. /// /// On Android, messages will be represented using `java.nio.ByteBuffer`. @@ -310,7 +312,7 @@ class StandardMessageCodec implements MessageCodec { ByteData? encodeMessage(Object? message) { if (message == null) return null; - final WriteBuffer buffer = WriteBuffer(startCapacity: 64); + final WriteBuffer buffer = WriteBuffer(startCapacity: _writeBufferStartCapacity); writeValue(buffer, message); return buffer.done(); } @@ -575,7 +577,7 @@ class StandardMethodCodec implements MethodCodec { @override ByteData encodeMethodCall(MethodCall methodCall) { - final WriteBuffer buffer = WriteBuffer(); + final WriteBuffer buffer = WriteBuffer(startCapacity: _writeBufferStartCapacity); messageCodec.writeValue(buffer, methodCall.method); messageCodec.writeValue(buffer, methodCall.arguments); return buffer.done(); @@ -594,7 +596,7 @@ class StandardMethodCodec implements MethodCodec { @override ByteData encodeSuccessEnvelope(Object? result) { - final WriteBuffer buffer = WriteBuffer(); + final WriteBuffer buffer = WriteBuffer(startCapacity: _writeBufferStartCapacity); buffer.putUint8(0); messageCodec.writeValue(buffer, result); return buffer.done(); @@ -602,7 +604,7 @@ class StandardMethodCodec implements MethodCodec { @override ByteData encodeErrorEnvelope({ required String code, String? message, Object? details}) { - final WriteBuffer buffer = WriteBuffer(); + final WriteBuffer buffer = WriteBuffer(startCapacity: _writeBufferStartCapacity); buffer.putUint8(1); messageCodec.writeValue(buffer, code); messageCodec.writeValue(buffer, message);