Reland GC tracking benchmarks (#82069)
This commit is contained in:
parent
9805df890f
commit
304b9c668e
@ -6,7 +6,7 @@ import 'package:flutter_driver/flutter_driver.dart';
|
|||||||
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
const String fileName = 'large_image_changer';
|
const String fileName = 'animated_image';
|
||||||
|
|
||||||
test('Animate for 250 frames', () async {
|
test('Animate for 250 frames', () async {
|
||||||
final FlutterDriver driver = await FlutterDriver.connect();
|
final FlutterDriver driver = await FlutterDriver.connect();
|
||||||
|
@ -9,8 +9,11 @@ import 'package:flutter_devicelab/tasks/perf_tests.dart';
|
|||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
deviceOperatingSystem = DeviceOperatingSystem.android;
|
deviceOperatingSystem = DeviceOperatingSystem.android;
|
||||||
await task(DevToolsMemoryTest(
|
await task(PerfTest(
|
||||||
'${flutterDirectory.path}/dev/benchmarks/macrobenchmarks',
|
'${flutterDirectory.path}/dev/benchmarks/macrobenchmarks',
|
||||||
'test_driver/animated_image.dart',
|
'test_driver/animated_image.dart',
|
||||||
|
'animated_image',
|
||||||
|
measureCpuGpu: true,
|
||||||
|
measureMemory: true,
|
||||||
).run);
|
).run);
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ class GalleryTransitionTest {
|
|||||||
: '${testFile}_test');
|
: '${testFile}_test');
|
||||||
section('DRIVE START');
|
section('DRIVE START');
|
||||||
await flutter('drive', options: <String>[
|
await flutter('drive', options: <String>[
|
||||||
|
'--no-dds',
|
||||||
'--profile',
|
'--profile',
|
||||||
if (needFullTimeline)
|
if (needFullTimeline)
|
||||||
'--trace-startup',
|
'--trace-startup',
|
||||||
|
@ -705,6 +705,7 @@ class PerfTest {
|
|||||||
final String deviceId = device.deviceId;
|
final String deviceId = device.deviceId;
|
||||||
|
|
||||||
await flutter('drive', options: <String>[
|
await flutter('drive', options: <String>[
|
||||||
|
'--no-dds', // TODO(dnfield): consider removing when https://github.com/flutter/flutter/issues/81707 is fixed
|
||||||
'--no-android-gradle-daemon',
|
'--no-android-gradle-daemon',
|
||||||
'-v',
|
'-v',
|
||||||
'--verbose-system-logs',
|
'--verbose-system-logs',
|
||||||
@ -777,6 +778,8 @@ const List<String> _kCommonScoreKeys = <String>[
|
|||||||
'worst_frame_rasterizer_time_millis',
|
'worst_frame_rasterizer_time_millis',
|
||||||
'90th_percentile_frame_rasterizer_time_millis',
|
'90th_percentile_frame_rasterizer_time_millis',
|
||||||
'99th_percentile_frame_rasterizer_time_millis',
|
'99th_percentile_frame_rasterizer_time_millis',
|
||||||
|
'new_gen_gc_count',
|
||||||
|
'old_gen_gc_count',
|
||||||
];
|
];
|
||||||
|
|
||||||
class PerfTestWithSkSL extends PerfTest {
|
class PerfTestWithSkSL extends PerfTest {
|
||||||
@ -868,6 +871,7 @@ class PerfTestWithSkSL extends PerfTest {
|
|||||||
_flutterPath,
|
_flutterPath,
|
||||||
<String>[
|
<String>[
|
||||||
'run',
|
'run',
|
||||||
|
'--no-dds',
|
||||||
if (deviceOperatingSystem == DeviceOperatingSystem.ios)
|
if (deviceOperatingSystem == DeviceOperatingSystem.ios)
|
||||||
...<String>[
|
...<String>[
|
||||||
'--device-timeout', '5',
|
'--device-timeout', '5',
|
||||||
|
@ -17,7 +17,11 @@ class FrameTimingSummarizer {
|
|||||||
/// Summarize `data` to frame build time and frame rasterizer time statistics.
|
/// Summarize `data` to frame build time and frame rasterizer time statistics.
|
||||||
///
|
///
|
||||||
/// See [TimelineSummary.summaryJson] for detail.
|
/// See [TimelineSummary.summaryJson] for detail.
|
||||||
factory FrameTimingSummarizer(List<FrameTiming> data) {
|
factory FrameTimingSummarizer(
|
||||||
|
List<FrameTiming> data, {
|
||||||
|
int? newGenGCCount,
|
||||||
|
int? oldGenGCCount,
|
||||||
|
}) {
|
||||||
assert(data != null);
|
assert(data != null);
|
||||||
assert(data.isNotEmpty);
|
assert(data.isNotEmpty);
|
||||||
final List<Duration> frameBuildTime = List<Duration>.unmodifiable(
|
final List<Duration> frameBuildTime = List<Duration>.unmodifiable(
|
||||||
@ -58,6 +62,8 @@ class FrameTimingSummarizer {
|
|||||||
p90VsyncOverhead: _findPercentile(vsyncOverheadSorted, 0.90),
|
p90VsyncOverhead: _findPercentile(vsyncOverheadSorted, 0.90),
|
||||||
p99VsyncOverhead: _findPercentile(vsyncOverheadSorted, 0.99),
|
p99VsyncOverhead: _findPercentile(vsyncOverheadSorted, 0.99),
|
||||||
worstVsyncOverhead: vsyncOverheadSorted.last,
|
worstVsyncOverhead: vsyncOverheadSorted.last,
|
||||||
|
newGenGCCount: newGenGCCount ?? -1,
|
||||||
|
oldGenGCCount: oldGenGCCount ?? -1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +85,8 @@ class FrameTimingSummarizer {
|
|||||||
required this.p90VsyncOverhead,
|
required this.p90VsyncOverhead,
|
||||||
required this.p99VsyncOverhead,
|
required this.p99VsyncOverhead,
|
||||||
required this.worstVsyncOverhead,
|
required this.worstVsyncOverhead,
|
||||||
|
required this.newGenGCCount,
|
||||||
|
required this.oldGenGCCount,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// List of frame build time in microseconds
|
/// List of frame build time in microseconds
|
||||||
@ -133,6 +141,12 @@ class FrameTimingSummarizer {
|
|||||||
/// The largest value of [vsyncOverhead] in milliseconds.
|
/// The largest value of [vsyncOverhead] in milliseconds.
|
||||||
final Duration worstVsyncOverhead;
|
final Duration worstVsyncOverhead;
|
||||||
|
|
||||||
|
/// The number of new generation GCs.
|
||||||
|
final int newGenGCCount;
|
||||||
|
|
||||||
|
/// The number of old generation GCs.
|
||||||
|
final int oldGenGCCount;
|
||||||
|
|
||||||
/// Convert the summary result to a json object.
|
/// Convert the summary result to a json object.
|
||||||
///
|
///
|
||||||
/// See [TimelineSummary.summaryJson] for detail.
|
/// See [TimelineSummary.summaryJson] for detail.
|
||||||
@ -162,6 +176,8 @@ class FrameTimingSummarizer {
|
|||||||
'frame_rasterizer_times': frameRasterizerTime
|
'frame_rasterizer_times': frameRasterizerTime
|
||||||
.map<int>((Duration datum) => datum.inMicroseconds)
|
.map<int>((Duration datum) => datum.inMicroseconds)
|
||||||
.toList(),
|
.toList(),
|
||||||
|
'new_gen_gc_count': newGenGCCount,
|
||||||
|
'old_gen_gc_count': oldGenGCCount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,8 +228,7 @@ https://flutter.dev/docs/testing/integration-tests#testing-on-firebase-test-lab
|
|||||||
_vmService = vmService;
|
_vmService = vmService;
|
||||||
}
|
}
|
||||||
if (_vmService == null) {
|
if (_vmService == null) {
|
||||||
final developer.ServiceProtocolInfo info =
|
final developer.ServiceProtocolInfo info = await developer.Service.getInfo();
|
||||||
await developer.Service.getInfo();
|
|
||||||
assert(info.serverUri != null);
|
assert(info.serverUri != null);
|
||||||
_vmService = await vm_io.vmServiceConnectUri(
|
_vmService = await vm_io.vmServiceConnectUri(
|
||||||
'ws://localhost:${info.serverUri!.port}${info.serverUri!.path}ws',
|
'ws://localhost:${info.serverUri!.port}${info.serverUri!.path}ws',
|
||||||
@ -302,6 +301,29 @@ https://flutter.dev/docs/testing/integration-tests#testing-on-firebase-test-lab
|
|||||||
reportData![reportKey] = timeline.toJson();
|
reportData![reportKey] = timeline.toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<_GarbageCollectionInfo> _runAndGetGCInfo(Future<void> Function() action) async {
|
||||||
|
if (kIsWeb) {
|
||||||
|
await action();
|
||||||
|
return const _GarbageCollectionInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
final vm.Timeline timeline = await traceTimeline(
|
||||||
|
action,
|
||||||
|
streams: <String>['GC'],
|
||||||
|
);
|
||||||
|
|
||||||
|
final int oldGenGCCount = timeline.traceEvents!.where((vm.TimelineEvent event) {
|
||||||
|
return event.json!['cat'] == 'GC' && event.json!['name'] == 'CollectOldGeneration';
|
||||||
|
}).length;
|
||||||
|
final int newGenGCCount = timeline.traceEvents!.where((vm.TimelineEvent event) {
|
||||||
|
return event.json!['cat'] == 'GC' && event.json!['name'] == 'CollectNewGeneration';
|
||||||
|
}).length;
|
||||||
|
return _GarbageCollectionInfo(
|
||||||
|
oldCount: oldGenGCCount,
|
||||||
|
newCount: newGenGCCount,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Watches the [FrameTiming] during `action` and report it to the binding
|
/// Watches the [FrameTiming] during `action` and report it to the binding
|
||||||
/// with key `reportKey`.
|
/// with key `reportKey`.
|
||||||
///
|
///
|
||||||
@ -340,11 +362,16 @@ https://flutter.dev/docs/testing/integration-tests#testing-on-firebase-test-lab
|
|||||||
await Future<void>.delayed(const Duration(seconds: 2)); // flush old FrameTimings
|
await Future<void>.delayed(const Duration(seconds: 2)); // flush old FrameTimings
|
||||||
final TimingsCallback watcher = frameTimings.addAll;
|
final TimingsCallback watcher = frameTimings.addAll;
|
||||||
addTimingsCallback(watcher);
|
addTimingsCallback(watcher);
|
||||||
await action();
|
final _GarbageCollectionInfo gcInfo = await _runAndGetGCInfo(action);
|
||||||
|
|
||||||
await delayForFrameTimings(); // make sure all FrameTimings are reported
|
await delayForFrameTimings(); // make sure all FrameTimings are reported
|
||||||
removeTimingsCallback(watcher);
|
removeTimingsCallback(watcher);
|
||||||
final FrameTimingSummarizer frameTimes =
|
|
||||||
FrameTimingSummarizer(frameTimings);
|
final FrameTimingSummarizer frameTimes = FrameTimingSummarizer(
|
||||||
|
frameTimings,
|
||||||
|
newGenGCCount: gcInfo.newCount,
|
||||||
|
oldGenGCCount: gcInfo.oldCount,
|
||||||
|
);
|
||||||
reportData ??= <String, dynamic>{};
|
reportData ??= <String, dynamic>{};
|
||||||
reportData![reportKey] = frameTimes.summary;
|
reportData![reportKey] = frameTimes.summary;
|
||||||
}
|
}
|
||||||
@ -381,3 +408,11 @@ https://flutter.dev/docs/testing/integration-tests#testing-on-firebase-test-lab
|
|||||||
// `LiveTestWidgetsFlutterBinding` https://github.com/flutter/flutter/issues/81534
|
// `LiveTestWidgetsFlutterBinding` https://github.com/flutter/flutter/issues/81534
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class _GarbageCollectionInfo {
|
||||||
|
const _GarbageCollectionInfo({this.oldCount = -1, this.newCount = -1});
|
||||||
|
|
||||||
|
final int oldCount;
|
||||||
|
final int newCount;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user