Skip to content

Commit 9fc160b

Browse files
authored
Run all microbenchmarks (flutter#154374)
Two things: **Re-land**: Uninstall microbenchmarks before running them. Flakes in flutter#153828 stem from adb saying the app isn't installed, but then failing to install wtih `-r`. Several other tests uninstall the app before trying to run it. Previous fix called uninstall between tests, but iOS takes 12 to 13 seconds to perform uninstall / install, which timed out the test. Just uninstall the one time since we only care about any lingering apps with different keys. Potential solution flutter#153828 **Make things go fast** Instead of installing 21 different compilations of the same app to get results; compile and run them together. Locally on Mac+iOS, this should takes ~3 minutes instead of ~15 minutes.
1 parent 0d8247e commit 9fc160b

26 files changed

+201
-105
lines changed
Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
# microbenchmarks
22

3-
To run these benchmarks on a device, first run `flutter logs' in one
4-
window to see the device logs, then, in a different window, run any of
5-
these:
3+
To run these benchmarks on a device, first run `flutter logs` in one
4+
window to see the device logs, then, in a different window, run:
65

76
```sh
8-
flutter run --release lib/gestures/velocity_tracker_bench.dart
9-
flutter run --release lib/gestures/gesture_detector_bench.dart
10-
flutter run --release lib/stocks/animation_bench.dart
11-
flutter run --release lib/stocks/build_bench.dart
12-
flutter run --release lib/stocks/layout_bench.dart
7+
flutter run -d $DEVICE_ID --profile lib/benchmark_collection.dart
138
```
149

1510
The results should be in the device logs.
1611

17-
### Avoid changing names of the benchmarks
12+
## Avoid changing names of the benchmarks
1813

1914
Each microbenchmark is identified by a name, for example,
20-
"catmullrom_transform_iteration". Changing the name of an existing
21-
microbenchmarks will effectively remove the old benchmark and create a new one,
15+
"catmullrom_transform_iteration". Changing the name passed to `BenchmarkResultPrinter.addResult`
16+
will effectively remove the old benchmark and create a new one,
2217
losing the historical data associated with the old benchmark in the process.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter_test/flutter_test.dart';
6+
7+
class BenchmarkingBinding extends LiveTestWidgetsFlutterBinding {
8+
BenchmarkingBinding();
9+
10+
final Stopwatch drawFrameWatch = Stopwatch();
11+
12+
@override
13+
void handleBeginFrame(Duration? rawTimeStamp) {
14+
drawFrameWatch.start();
15+
super.handleBeginFrame(rawTimeStamp);
16+
}
17+
18+
@override
19+
void handleDrawFrame() {
20+
super.handleDrawFrame();
21+
drawFrameWatch.stop();
22+
}
23+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:io';
6+
7+
import 'package:flutter/material.dart';
8+
import 'package:flutter/scheduler.dart';
9+
import 'package:flutter_test/flutter_test.dart';
10+
11+
import 'benchmark_binding.dart';
12+
import 'foundation/all_elements_bench.dart' as all_elements_bench;
13+
import 'foundation/change_notifier_bench.dart' as change_notifier_bench;
14+
import 'foundation/clamp.dart' as clamp;
15+
import 'foundation/decode_and_parse_asset_manifest.dart'
16+
as decode_and_parse_asset_manifest;
17+
import 'foundation/platform_asset_bundle.dart' as platform_asset_bundle;
18+
import 'foundation/standard_message_codec_bench.dart'
19+
as standard_message_codec_bench;
20+
import 'foundation/standard_method_codec_bench.dart'
21+
as standard_method_codec_bench;
22+
import 'foundation/timeline_bench.dart' as timeline_bench;
23+
import 'geometry/matrix_utils_transform_bench.dart'
24+
as matrix_utils_transform_bench;
25+
import 'geometry/rrect_contains_bench.dart' as rrect_contains_bench;
26+
import 'gestures/gesture_detector_bench.dart' as gesture_detector_bench;
27+
import 'gestures/velocity_tracker_bench.dart' as velocity_tracker_bench;
28+
import 'language/compute_bench.dart' as compute_bench;
29+
import 'language/sync_star_bench.dart' as sync_star_bench;
30+
import 'language/sync_star_semantics_bench.dart' as sync_star_semantics_bench;
31+
import 'layout/text_intrinsic_bench.dart' as text_intrinsic_bench;
32+
import 'stocks/animation_bench.dart' as animation_bench;
33+
import 'stocks/build_bench.dart' as build_bench;
34+
import 'stocks/build_bench_profiled.dart' as build_bench_profiled;
35+
import 'stocks/layout_bench.dart' as layout_bench;
36+
import 'ui/image_bench.dart' as image_bench;
37+
38+
typedef Benchmark = (String name, Future<void> Function() value);
39+
40+
Future<void> main() async {
41+
assert(false,
42+
"Don't run benchmarks in debug mode! Use 'flutter run --release'.");
43+
44+
// BenchmarkingBinding is used by animation_bench, providing a simple
45+
// stopwatch interface over rendering. Lifting it here makes all
46+
// benchmarks run together.
47+
final BenchmarkingBinding binding = BenchmarkingBinding();
48+
final List<Benchmark> benchmarks = <Benchmark>[
49+
('foundation/change_notifier_bench.dart', change_notifier_bench.execute),
50+
('foundation/clamp.dart', clamp.execute),
51+
('foundation/platform_asset_bundle.dart', platform_asset_bundle.execute),
52+
(
53+
'foundation/standard_message_codec_bench.dart',
54+
standard_message_codec_bench.execute
55+
),
56+
(
57+
'foundation/standard_method_codec_bench.dart',
58+
standard_method_codec_bench.execute
59+
),
60+
('foundation/timeline_bench.dart', timeline_bench.execute),
61+
(
62+
'foundation/decode_and_parse_asset_manifest.dart',
63+
decode_and_parse_asset_manifest.execute
64+
),
65+
(
66+
'geometry/matrix_utils_transform_bench.dart',
67+
matrix_utils_transform_bench.execute
68+
),
69+
('geometry/rrect_contains_bench.dart', rrect_contains_bench.execute),
70+
('gestures/gesture_detector_bench.dart', gesture_detector_bench.execute),
71+
('gestures/velocity_tracker_bench.dart', velocity_tracker_bench.execute),
72+
('language/compute_bench.dart', compute_bench.execute),
73+
('language/sync_star_bench.dart', sync_star_bench.execute),
74+
(
75+
'language/sync_star_semantics_bench.dart',
76+
sync_star_semantics_bench.execute
77+
),
78+
('stocks/animation_bench.dart', () => animation_bench.execute(binding)),
79+
('stocks/build_bench.dart', build_bench.execute),
80+
('stocks/build_bench_profiled.dart', build_bench_profiled.execute),
81+
('stocks/layout_bench.dart', layout_bench.execute),
82+
('ui/image_bench.dart', image_bench.execute),
83+
('layout/text_intrinsic_bench.dart', text_intrinsic_bench.execute),
84+
(
85+
'foundation/all_elements_bench.dart',
86+
() async {
87+
binding.framePolicy =
88+
LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
89+
runApp(const SizedBox.shrink()); // ensure dispose
90+
await SchedulerBinding.instance.endOfFrame;
91+
all_elements_bench.execute();
92+
}
93+
),
94+
];
95+
96+
print('╡ ••• Running microbenchmarks ••• ╞');
97+
98+
for (final Benchmark mark in benchmarks) {
99+
// Reset the frame policy to default - each test can set it on their own.
100+
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fadePointers;
101+
print('╡ ••• Running ${mark.$1} ••• ╞');
102+
await mark.$2();
103+
}
104+
105+
print('\n\n╡ ••• Done ••• ╞\n\n');
106+
exit(0);
107+
}

dev/benchmarks/microbenchmarks/lib/foundation/all_elements_bench.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ import '../common.dart';
1111

1212
const int _kNumIters = 10000;
1313

14-
Future<void> main() async {
15-
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
14+
Future<void> execute() async {
1615
runApp(MaterialApp(
1716
home: Scaffold(
1817
body: GridView.count(

dev/benchmarks/microbenchmarks/lib/foundation/change_notifier_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const int _kNumIterations = 65536;
1010
const int _kNumWarmUp = 100;
1111
const int _kScale = 1000;
1212

13-
void main() {
13+
Future<void> execute() async {
1414
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1515

1616
// In the following benchmarks, we won't remove the listeners when we don't

dev/benchmarks/microbenchmarks/lib/foundation/clamp.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import '../common.dart';
99
const int _kBatchSize = 100000;
1010
const int _kNumIterations = 1000;
1111

12-
void main() {
12+
Future<void> execute() async {
1313
assert(false,
1414
"Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1515
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();

dev/benchmarks/microbenchmarks/lib/foundation/decode_and_parse_asset_manifest.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import '../common.dart';
99

1010
const int _kNumIterations = 1000;
1111

12-
void main() async {
12+
Future<void> execute() async {
1313
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1414

1515
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();

dev/benchmarks/microbenchmarks/lib/foundation/platform_asset_bundle.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import '../common.dart';
1010
const int _kBatchSize = 100;
1111
const int _kNumIterations = 100;
1212

13-
void main() async {
13+
Future<void> execute() async {
1414
assert(false,
1515
"Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1616
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();

dev/benchmarks/microbenchmarks/lib/foundation/standard_message_codec_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import '../common.dart';
88

99
const int _kNumIterations = 100000;
1010

11-
void main() {
11+
Future<void> execute() async {
1212
assert(false,
1313
"Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1414
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();

dev/benchmarks/microbenchmarks/lib/foundation/standard_method_codec_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import '../common.dart';
88

99
const int _kNumIterations = 100000;
1010

11-
void main() {
11+
Future<void> execute() async {
1212
assert(false,
1313
"Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1414
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();

dev/benchmarks/microbenchmarks/lib/foundation/timeline_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import '../common.dart';
88

99
const int _kNumIterations = 10000;
1010

11-
void main() {
11+
Future<void> execute() async {
1212
assert(false,
1313
"Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1414
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();

dev/benchmarks/microbenchmarks/lib/geometry/matrix_utils_transform_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import '../common.dart';
1111
const int _kNumIterations = 10000000;
1212
const int _kNumWarmUp = 100000;
1313

14-
void main() {
14+
Future<void> execute() async {
1515
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1616
print('MatrixUtils.transformRect and .transformPoint benchmark...');
1717

dev/benchmarks/microbenchmarks/lib/geometry/rrect_contains_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import '../common.dart';
88

99
const int _kNumIters = 10000;
1010

11-
void main() {
11+
Future<void> execute() async {
1212
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1313
final Stopwatch watch = Stopwatch();
1414
print('RRect contains benchmark...');

dev/benchmarks/microbenchmarks/lib/gestures/gesture_detector_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import 'apps/button_matrix_app.dart' as button_matrix;
1010
const int _kNumWarmUpIters = 20;
1111
const int _kNumIters = 300;
1212

13-
Future<void> main() async {
13+
Future<void> execute() async {
1414
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1515
final Stopwatch watch = Stopwatch();
1616
print('GestureDetector semantics benchmark...');

dev/benchmarks/microbenchmarks/lib/gestures/velocity_tracker_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class TrackerBenchmark {
1717
final String name;
1818
}
1919

20-
Future<void> main() async {
20+
Future<void> execute() async {
2121
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
2222
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();
2323
final List<TrackerBenchmark> benchmarks = <TrackerBenchmark>[

dev/benchmarks/microbenchmarks/lib/language/compute_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ List<Data> test(int length) {
2323
(int index) => Data(index * index));
2424
}
2525

26-
Future<void> main() async {
26+
Future<void> execute() async {
2727
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
2828

2929
// Warm up lap

dev/benchmarks/microbenchmarks/lib/language/sync_star_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import '../common.dart';
77
const int _kNumIterations = 1000;
88
const int _kNumWarmUp = 100;
99

10-
void main() {
10+
Future<void> execute() async {
1111
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
1212

1313
// Warm up lap

dev/benchmarks/microbenchmarks/lib/language/sync_star_semantics_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import '../common.dart';
99
const int _kNumIterations = 1000;
1010
const int _kNumWarmUp = 100;
1111

12-
void main() {
12+
Future<void> execute() async {
1313
final List<String> words = 'Lorem Ipsum is simply dummy text of the printing and'
1414
" typesetting industry. Lorem Ipsum has been the industry's"
1515
' standard dummy text ever since the 1500s, when an unknown'

dev/benchmarks/microbenchmarks/lib/layout/text_intrinsic_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ final Widget intrinsicTextHeight = Directionality(
2020
),
2121
);
2222

23-
Future<void> main() async {
23+
Future<void> execute() async {
2424
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
2525

2626
// We control the framePolicy below to prevent us from scheduling frames in

dev/benchmarks/microbenchmarks/lib/stocks/animation_bench.dart

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,16 @@ import 'package:flutter_test/flutter_test.dart';
77
import 'package:stocks/main.dart' as stocks;
88
import 'package:stocks/stock_data.dart' as stock_data;
99

10+
import '../benchmark_binding.dart';
1011
import '../common.dart';
1112

1213
const Duration kBenchmarkTime = Duration(seconds: 15);
1314

14-
class BenchmarkingBinding extends LiveTestWidgetsFlutterBinding {
15-
BenchmarkingBinding(this.stopwatch);
16-
17-
final Stopwatch stopwatch;
18-
19-
@override
20-
void handleBeginFrame(Duration? rawTimeStamp) {
21-
stopwatch.start();
22-
super.handleBeginFrame(rawTimeStamp);
23-
}
24-
25-
@override
26-
void handleDrawFrame() {
27-
super.handleDrawFrame();
28-
stopwatch.stop();
29-
}
30-
}
31-
32-
Future<void> main() async {
15+
Future<void> execute(BenchmarkingBinding binding) async {
3316
assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'.");
3417
stock_data.StockData.actuallyFetchData = false;
3518

3619
final Stopwatch wallClockWatch = Stopwatch();
37-
final Stopwatch cpuWatch = Stopwatch();
38-
BenchmarkingBinding(cpuWatch);
3920

4021
int totalOpenFrameElapsedMicroseconds = 0;
4122
int totalOpenIterationCount = 0;
@@ -52,27 +33,27 @@ Future<void> main() async {
5233
bool drawerIsOpen = false;
5334
wallClockWatch.start();
5435
while (wallClockWatch.elapsed < kBenchmarkTime) {
55-
cpuWatch.reset();
36+
binding.drawFrameWatch.reset();
5637
if (drawerIsOpen) {
5738
await tester.tapAt(const Offset(780.0, 250.0)); // Close drawer
5839
await tester.pump();
5940
totalCloseIterationCount += 1;
60-
totalCloseFrameElapsedMicroseconds += cpuWatch.elapsedMicroseconds;
41+
totalCloseFrameElapsedMicroseconds += binding.drawFrameWatch.elapsedMicroseconds;
6142
} else {
6243
await tester.tapAt(const Offset(20.0, 50.0)); // Open drawer
6344
await tester.pump();
6445
totalOpenIterationCount += 1;
65-
totalOpenFrameElapsedMicroseconds += cpuWatch.elapsedMicroseconds;
46+
totalOpenFrameElapsedMicroseconds += binding.drawFrameWatch.elapsedMicroseconds;
6647
}
6748
drawerIsOpen = !drawerIsOpen;
6849

6950
// Time how long each frame takes
70-
cpuWatch.reset();
51+
binding.drawFrameWatch.reset();
7152
while (SchedulerBinding.instance.hasScheduledFrame) {
7253
await tester.pump();
7354
totalSubsequentFramesIterationCount += 1;
7455
}
75-
totalSubsequentFramesElapsedMicroseconds += cpuWatch.elapsedMicroseconds;
56+
totalSubsequentFramesElapsedMicroseconds += binding.drawFrameWatch.elapsedMicroseconds;
7657
}
7758
});
7859

dev/benchmarks/microbenchmarks/lib/stocks/build_bench.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Future<List<double>> runBuildBenchmark() async {
5555
return values;
5656
}
5757

58-
Future<void> main() async {
58+
Future<void> execute() async {
5959
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();
6060
printer.addResultStatistics(
6161
description: 'Stock build',

dev/benchmarks/microbenchmarks/lib/stocks/build_bench_profiled.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'package:flutter_test/flutter_test.dart';
88
import '../common.dart';
99
import 'build_bench.dart';
1010

11-
Future<void> main() async {
11+
Future<void> execute() async {
1212
debugProfileBuildsEnabledUserWidgets = true;
1313
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();
1414
printer.addResultStatistics(

0 commit comments

Comments
 (0)