From f92884c7b846d0fde13a8c332ac648977fc9b631 Mon Sep 17 00:00:00 2001 From: Jia Hao Date: Thu, 21 Sep 2023 00:20:09 +0000 Subject: [PATCH] Rename `debugProfilePlatformChannels` to a constant that works in release mode (#134922) When it comes to startup profiling, it is very helpful to look at platform channels. `debugProfilePlatformChannels` today only works in debug and profile mode. Unfortunately, using profile mode is less accurate for startup profiling, because of the service isolate introducing additional overhead. This PR allows this toggle to work in release mode. Note that there are two parts to `debugProfilePlatformChannels`: - Adding timeline events - Logging statistics about platform channels I also considered adding a separate toggle to limit the scope of this change to the former, but that seems like complexity that we might not need at this time. Towards #102189 --- packages/flutter/lib/src/services/debug.dart | 14 +---- .../lib/src/services/platform_channel.dart | 56 ++++++++++--------- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/packages/flutter/lib/src/services/debug.dart b/packages/flutter/lib/src/services/debug.dart index 518c29c5359..ce63157aaf7 100644 --- a/packages/flutter/lib/src/services/debug.dart +++ b/packages/flutter/lib/src/services/debug.dart @@ -15,18 +15,6 @@ export 'hardware_keyboard.dart' show KeyDataTransitMode; /// of their extent of support for keyboard API. KeyDataTransitMode? debugKeyEventSimulatorTransitModeOverride; -/// Profile and print statistics on Platform Channel usage. -/// -/// When this is true statistics about the usage of Platform Channels will be -/// printed out periodically to the console and Timeline events will show the -/// time between sending and receiving a message (encoding and decoding time -/// excluded). -/// -/// The statistics include the total bytes transmitted and the average number of -/// bytes per invocation in the last quantum. "Up" means in the direction of -/// Flutter to the host platform, "down" is the host platform to flutter. -bool debugProfilePlatformChannels = false; - /// Setting to true will cause extensive logging to occur when key events are /// received. /// @@ -46,7 +34,7 @@ bool debugAssertAllServicesVarsUnset(String reason) { if (debugKeyEventSimulatorTransitModeOverride != null) { throw FlutterError(reason); } - if (debugProfilePlatformChannels || debugPrintKeyboardEvents) { + if (debugPrintKeyboardEvents) { throw FlutterError(reason); } return true; diff --git a/packages/flutter/lib/src/services/platform_channel.dart b/packages/flutter/lib/src/services/platform_channel.dart index 2e1308d2811..cba9e1654d4 100644 --- a/packages/flutter/lib/src/services/platform_channel.dart +++ b/packages/flutter/lib/src/services/platform_channel.dart @@ -12,7 +12,6 @@ import '_background_isolate_binary_messenger_io.dart' import 'binary_messenger.dart'; import 'binding.dart'; -import 'debug.dart' show debugProfilePlatformChannels; import 'message_codec.dart'; import 'message_codecs.dart'; @@ -23,9 +22,21 @@ export 'binary_messenger.dart' show BinaryMessenger; export 'binding.dart' show RootIsolateToken; export 'message_codec.dart' show MessageCodec, MethodCall, MethodCodec; -bool _debugProfilePlatformChannelsIsRunning = false; -const Duration _debugProfilePlatformChannelsRate = Duration(seconds: 1); -final Expando _debugBinaryMessengers = Expando(); +/// Profile and print statistics on Platform Channel usage. +/// +/// When this is true statistics about the usage of Platform Channels will be +/// printed out periodically to the console and Timeline events will show the +/// time between sending and receiving a message (encoding and decoding time +/// excluded). +/// +/// The statistics include the total bytes transmitted and the average number of +/// bytes per invocation in the last quantum. "Up" means in the direction of +/// Flutter to the host platform, "down" is the host platform to flutter. +const bool kProfilePlatformChannels = false; + +bool _profilePlatformChannelsIsRunning = false; +const Duration _profilePlatformChannelsRate = Duration(seconds: 1); +final Expando _profiledBinaryMessengers = Expando(); class _ProfiledBinaryMessenger implements BinaryMessenger { const _ProfiledBinaryMessenger(this.proxy, this.channelTypeName, this.codecTypeName); @@ -40,17 +51,12 @@ class _ProfiledBinaryMessenger implements BinaryMessenger { Future? sendWithPostfix(String channel, String postfix, ByteData? message) async { _debugRecordUpStream(channelTypeName, '$channel$postfix', codecTypeName, message); - TimelineTask? debugTimelineTask; - if (!kReleaseMode) { - debugTimelineTask = TimelineTask()..start('Platform Channel send $channel$postfix'); - } + final TimelineTask timelineTask = TimelineTask()..start('Platform Channel send $channel$postfix'); final ByteData? result; try { result = await proxy.send(channel, message); } finally { - if (!kReleaseMode) { - debugTimelineTask!.finish(); - } + timelineTask.finish(); } _debugRecordDownStream(channelTypeName, '$channel$postfix', codecTypeName, result); return result; @@ -93,17 +99,17 @@ class _PlatformChannelStats { double get averageDownPayload => _downBytes / _downCount; } -final Map _debugProfilePlatformChannelsStats = {}; +final Map _profilePlatformChannelsStats = {}; Future _debugLaunchProfilePlatformChannels() async { - if (!_debugProfilePlatformChannelsIsRunning) { - _debugProfilePlatformChannelsIsRunning = true; - await Future.delayed(_debugProfilePlatformChannelsRate); - _debugProfilePlatformChannelsIsRunning = false; + if (!_profilePlatformChannelsIsRunning) { + _profilePlatformChannelsIsRunning = true; + await Future.delayed(_profilePlatformChannelsRate); + _profilePlatformChannelsIsRunning = false; final StringBuffer log = StringBuffer(); log.writeln('Platform Channel Stats:'); final List<_PlatformChannelStats> allStats = - _debugProfilePlatformChannelsStats.values.toList(); + _profilePlatformChannelsStats.values.toList(); // Sort highest combined bandwidth first. allStats.sort((_PlatformChannelStats x, _PlatformChannelStats y) => (y.upBytes + y.downBytes) - (x.upBytes + x.downBytes)); @@ -112,14 +118,14 @@ Future _debugLaunchProfilePlatformChannels() async { ' (name:"${stats.channel}" type:"${stats.type}" codec:"${stats.codec}" upBytes:${stats.upBytes} upBytes_avg:${stats.averageUpPayload.toStringAsFixed(1)} downBytes:${stats.downBytes} downBytes_avg:${stats.averageDownPayload.toStringAsFixed(1)})'); } debugPrint(log.toString()); - _debugProfilePlatformChannelsStats.clear(); + _profilePlatformChannelsStats.clear(); } } void _debugRecordUpStream(String channelTypeName, String name, String codecTypeName, ByteData? bytes) { final _PlatformChannelStats stats = - _debugProfilePlatformChannelsStats[name] ??= + _profilePlatformChannelsStats[name] ??= _PlatformChannelStats(name, codecTypeName, channelTypeName); stats.addUpStream(bytes?.lengthInBytes ?? 0); _debugLaunchProfilePlatformChannels(); @@ -128,7 +134,7 @@ void _debugRecordUpStream(String channelTypeName, String name, void _debugRecordDownStream(String channelTypeName, String name, String codecTypeName, ByteData? bytes) { final _PlatformChannelStats stats = - _debugProfilePlatformChannelsStats[name] ??= + _profilePlatformChannelsStats[name] ??= _PlatformChannelStats(name, codecTypeName, channelTypeName); stats.addDownStream(bytes?.lengthInBytes ?? 0); _debugLaunchProfilePlatformChannels(); @@ -184,8 +190,8 @@ class BasicMessageChannel { /// [BackgroundIsolateBinaryMessenger.ensureInitialized]. BinaryMessenger get binaryMessenger { final BinaryMessenger result = _binaryMessenger ?? _findBinaryMessenger(); - return !kReleaseMode && debugProfilePlatformChannels - ? _debugBinaryMessengers[this] ??= _ProfiledBinaryMessenger( + return kProfilePlatformChannels + ? _profiledBinaryMessengers[this] ??= _ProfiledBinaryMessenger( // ignore: no_runtimetype_tostring result, runtimeType.toString(), codec.runtimeType.toString()) : result; @@ -273,8 +279,8 @@ class MethodChannel { /// [BackgroundIsolateBinaryMessenger.ensureInitialized]. BinaryMessenger get binaryMessenger { final BinaryMessenger result = _binaryMessenger ?? _findBinaryMessenger(); - return !kReleaseMode && debugProfilePlatformChannels - ? _debugBinaryMessengers[this] ??= _ProfiledBinaryMessenger( + return kProfilePlatformChannels + ? _profiledBinaryMessengers[this] ??= _ProfiledBinaryMessenger( // ignore: no_runtimetype_tostring result, runtimeType.toString(), codec.runtimeType.toString()) : result; @@ -304,7 +310,7 @@ class MethodChannel { Future _invokeMethod(String method, { required bool missingOk, dynamic arguments }) async { final ByteData input = codec.encodeMethodCall(MethodCall(method, arguments)); final ByteData? result = - !kReleaseMode && debugProfilePlatformChannels ? + kProfilePlatformChannels ? await (binaryMessenger as _ProfiledBinaryMessenger).sendWithPostfix(name, '#$method', input) : await binaryMessenger.send(name, input); if (result == null) {