From 6ade39235c1392de61d813d681c9842cdbc171ed Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 7 Jul 2020 19:34:03 -0700 Subject: [PATCH] benchmark memory usage for grid view of memory intensive widgets (#61025) --- .../macrobenchmarks/lib/common.dart | 1 + dev/benchmarks/macrobenchmarks/lib/main.dart | 9 ++++ .../lib/src/heavy_grid_view.dart | 32 +++++++++++++ .../test_memory/heavy_gridview.dart | 24 ++++++++++ .../fast_scroll_heavy_gridview__memory.dart | 45 +++++++++++++++++++ dev/devicelab/manifest.yaml | 8 ++++ 6 files changed, 119 insertions(+) create mode 100644 dev/benchmarks/macrobenchmarks/lib/src/heavy_grid_view.dart create mode 100644 dev/benchmarks/macrobenchmarks/test_memory/heavy_gridview.dart create mode 100644 dev/devicelab/bin/tasks/fast_scroll_heavy_gridview__memory.dart diff --git a/dev/benchmarks/macrobenchmarks/lib/common.dart b/dev/benchmarks/macrobenchmarks/lib/common.dart index 3563a09ddc2a5..8e49f7aad037c 100644 --- a/dev/benchmarks/macrobenchmarks/lib/common.dart +++ b/dev/benchmarks/macrobenchmarks/lib/common.dart @@ -15,5 +15,6 @@ const String kColorFilterAndFadeRouteName = '/color_filter_and_fade'; const String kFadingChildAnimationRouteName = '/fading_child_animation'; const String kImageFilteredTransformAnimationRouteName = '/imagefiltered_transform_animation'; const String kMultiWidgetConstructionRouteName = '/multi_widget_construction'; +const String kHeavyGridViewRouteName = '/heavy_gridview'; const String kScrollableName = '/macrobenchmark_listview'; diff --git a/dev/benchmarks/macrobenchmarks/lib/main.dart b/dev/benchmarks/macrobenchmarks/lib/main.dart index 5bd15d858ea83..7c2a91fc2d655 100644 --- a/dev/benchmarks/macrobenchmarks/lib/main.dart +++ b/dev/benchmarks/macrobenchmarks/lib/main.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:macrobenchmarks/src/color_filter_and_fade.dart'; +import 'package:macrobenchmarks/src/heavy_grid_view.dart'; import 'package:macrobenchmarks/src/large_images.dart'; import 'package:macrobenchmarks/src/picture_cache.dart'; @@ -45,6 +46,7 @@ class MacrobenchmarksApp extends StatelessWidget { kFadingChildAnimationRouteName: (BuildContext context) => const FilteredChildAnimationPage(FilterType.opacity), kImageFilteredTransformAnimationRouteName: (BuildContext context) => const FilteredChildAnimationPage(FilterType.rotateFilter), kMultiWidgetConstructionRouteName: (BuildContext context) => const MultiWidgetConstructTable(10, 20), + kHeavyGridViewRouteName: (BuildContext context) => HeavyGridViewPage(), }, ); } @@ -151,6 +153,13 @@ class HomePage extends StatelessWidget { Navigator.pushNamed(context, kMultiWidgetConstructionRouteName); }, ), + RaisedButton( + key: const Key(kHeavyGridViewRouteName), + child: const Text('Heavy Grid View'), + onPressed: () { + Navigator.pushNamed(context, kHeavyGridViewRouteName); + }, + ), ], ), ); diff --git a/dev/benchmarks/macrobenchmarks/lib/src/heavy_grid_view.dart b/dev/benchmarks/macrobenchmarks/lib/src/heavy_grid_view.dart new file mode 100644 index 0000000000000..bbe90e897bab4 --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/lib/src/heavy_grid_view.dart @@ -0,0 +1,32 @@ +// 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/material.dart'; + +class HeavyGridViewPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return GridView.builder( + itemCount: 1000, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3), + itemBuilder: (BuildContext context, int index) => HeavyWidget(index), + ).build(context); + } +} + +class HeavyWidget extends StatelessWidget { + HeavyWidget(this.index) : super(key: ValueKey(index)); + + final int index; + final List _weight = List(1000000); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: 200, + height: 200, + child: Text('$index: ${_weight.length}'), + ); + } +} diff --git a/dev/benchmarks/macrobenchmarks/test_memory/heavy_gridview.dart b/dev/benchmarks/macrobenchmarks/test_memory/heavy_gridview.dart new file mode 100644 index 0000000000000..b814f8dbcda42 --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/test_memory/heavy_gridview.dart @@ -0,0 +1,24 @@ +// 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 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:macrobenchmarks/common.dart'; +import 'package:macrobenchmarks/main.dart'; + +Future endOfAnimation() async { + do { + await SchedulerBinding.instance.endOfFrame; + } while (SchedulerBinding.instance.hasScheduledFrame); +} + +Future main() async { + runApp(const MacrobenchmarksApp(initialRoute: kHeavyGridViewRouteName)); + await endOfAnimation(); + await Future.delayed(const Duration(milliseconds: 50)); + debugPrint('==== MEMORY BENCHMARK ==== READY ===='); +} diff --git a/dev/devicelab/bin/tasks/fast_scroll_heavy_gridview__memory.dart b/dev/devicelab/bin/tasks/fast_scroll_heavy_gridview__memory.dart new file mode 100644 index 0000000000000..f9697c1ef1089 --- /dev/null +++ b/dev/devicelab/bin/tasks/fast_scroll_heavy_gridview__memory.dart @@ -0,0 +1,45 @@ +// 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 'dart:async'; + +import 'package:flutter_devicelab/framework/adb.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/framework/utils.dart'; +import 'package:flutter_devicelab/tasks/perf_tests.dart'; + +const String kPackageName = 'com.example.macrobenchmarks'; +const String kActivityName = 'com.example.macrobenchmarks.MainActivity'; + +class FastScrollHeavyGridViewMemoryTest extends MemoryTest { + FastScrollHeavyGridViewMemoryTest() + : super( + '${flutterDirectory.path}/dev/benchmarks/macrobenchmarks', + 'test_memory/heavy_gridview.dart', kPackageName, + ); + + @override + AndroidDevice get device => super.device as AndroidDevice; + + @override + int get iterationCount => 5; + + @override + Future useMemory() async { + await launchApp(); + await recordStart(); + await device.shellExec('input', ['swipe', '50 1500 50 50 50']); + await Future.delayed(const Duration(milliseconds: 1500)); + await device.shellExec('input', ['swipe', '50 1500 50 50 50']); + await Future.delayed(const Duration(milliseconds: 1500)); + await device.shellExec('input', ['swipe', '50 1500 50 50 50']); + await Future.delayed(const Duration(milliseconds: 1500)); + await recordEnd(); + } +} + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.android; + await task(FastScrollHeavyGridViewMemoryTest().run); +} diff --git a/dev/devicelab/manifest.yaml b/dev/devicelab/manifest.yaml index e81afc7a28eda..1bdf9d60dd9e9 100644 --- a/dev/devicelab/manifest.yaml +++ b/dev/devicelab/manifest.yaml @@ -803,6 +803,14 @@ tasks: stage: devicelab required_agent_capabilities: ["mac/android"] + fast_scroll_heavy_gridview__memory: + description: > + Measures memory usage for scrolling through a grid view of heavy memory + usage widgets. + stage: devicelab + required_agent_capabilities: ["linux/android"] + flaky: true + animated_placeholder_perf: description: > Measures frame build and rasterizer times, as well as frame build counts