Skip to content

Commit

Permalink
Add 90th and 99th percentile frame rasterize time for timeline_summary (
Browse files Browse the repository at this point in the history
flutter#18881)

Our first step towards flutter#18727
  • Loading branch information
liyuqian authored Jun 28, 2018
1 parent 183ed46 commit 35e8cd8
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
20 changes: 20 additions & 0 deletions packages/flutter_driver/lib/src/driver/timeline_summary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ class TimelineSummary {
return _maxInMillis(_extractDuration(_extractGpuRasterizerDrawEvents()));
}

/// The [p]-th percentile frame rasterization time in milliseconds.
///
/// Returns null if no frames were recorded.
double computePercentileFrameRasterizerTimeMillis(double p) {
return _percentileInMillis(_extractDuration(_extractGpuRasterizerDrawEvents()), p);
}

/// The number of frames that missed the [kBuildBudget] on the GPU and
/// therefore are in the danger of missing frames.
int computeMissedFrameRasterizerBudgetCount([Duration frameBuildBudget = kBuildBudget]) => _extractGpuRasterizerDrawEvents()
Expand All @@ -76,6 +83,8 @@ class TimelineSummary {
'worst_frame_build_time_millis': computeWorstFrameBuildTimeMillis(),
'missed_frame_build_budget_count': computeMissedFrameBuildBudgetCount(),
'average_frame_rasterizer_time_millis': computeAverageFrameRasterizerTimeMillis(),
'90th_percentile_frame_rasterizer_time_millis': computePercentileFrameRasterizerTimeMillis(90.0),
'99th_percentile_frame_rasterizer_time_millis': computePercentileFrameRasterizerTimeMillis(99.0),
'worst_frame_rasterizer_time_millis': computeWorstFrameRasterizerTimeMillis(),
'missed_frame_rasterizer_budget_count': computeMissedFrameRasterizerBudgetCount(),
'frame_count': countFrames(),
Expand Down Expand Up @@ -159,6 +168,17 @@ class TimelineSummary {
return total / durations.length;
}

double _percentileInMillis(Iterable<Duration> durations, double percentile) {
if (durations.isEmpty)
return null;

assert(percentile >= 0.0 && percentile <= 100.0);
final List<double> doubles = durations.map<double>((Duration duration) => duration.inMilliseconds.toDouble()).toList();
doubles.sort();
return doubles[((doubles.length - 1) * (percentile / 100)).round()];

}

double _maxInMillis(Iterable<Duration> durations) {
if (durations.isEmpty)
return null;
Expand Down
53 changes: 53 additions & 0 deletions packages/flutter_driver/test/src/timeline_summary_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ void main() {
'name': 'GPURasterizer::Draw', 'ph': 'E', 'ts': timeStamp
};

List<Map<String, dynamic>> rasterizeTimeSequenceInMillis(List<int> sequence) {
final List<Map<String, dynamic>> result = <Map<String, dynamic>>[];
int t = 0;
for(int duration in sequence) {
result.add(begin(t));
t += duration * 1000;
result.add(end(t));
}
return result;
}

group('frame_count', () {
test('counts frames', () {
expect(
Expand Down Expand Up @@ -174,6 +185,44 @@ void main() {
});
});

group('percentile_frame_rasterizer_time_millis', () {
test('returns null when there is no data', () {
expect(summarize(<Map<String, dynamic>>[]).computeWorstFrameRasterizerTimeMillis(), isNull);
});

const List<List<int>> sequences = <List<int>>[
<int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
<int>[1, 2, 3, 4, 5],
<int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
];

const List<int> p90s = <int>[
9,
5,
18
];

test('computes 90th frame rasterizer time in milliseconds', () {
for(int i = 0; i < sequences.length; ++i) {
expect(
summarize(rasterizeTimeSequenceInMillis(sequences[i])).computePercentileFrameRasterizerTimeMillis(90.0),
p90s[i]
);
}
});

test('compute 99th frame rasterizer time in milliseconds', () {
final List<int> sequence = <int>[];
for(int i = 1; i <= 100; ++i) {
sequence.add(i);
}
expect(
summarize(rasterizeTimeSequenceInMillis(sequence)).computePercentileFrameRasterizerTimeMillis(99.0),
99
);
});
});

group('computeMissedFrameRasterizerBudgetCount', () {
test('computes the number of missed rasterizer budgets', () {
final TimelineSummary summary = summarize(<Map<String, dynamic>>[
Expand Down Expand Up @@ -202,6 +251,8 @@ void main() {
'worst_frame_build_time_millis': 11.0,
'missed_frame_build_budget_count': 2,
'average_frame_rasterizer_time_millis': 8.0,
'90th_percentile_frame_rasterizer_time_millis': 12.0,
'99th_percentile_frame_rasterizer_time_millis': 12.0,
'worst_frame_rasterizer_time_millis': 12.0,
'missed_frame_rasterizer_budget_count': 2,
'frame_count': 3,
Expand Down Expand Up @@ -250,6 +301,8 @@ void main() {
'worst_frame_build_time_millis': 11.0,
'missed_frame_build_budget_count': 2,
'average_frame_rasterizer_time_millis': 8.0,
'90th_percentile_frame_rasterizer_time_millis': 12.0,
'99th_percentile_frame_rasterizer_time_millis': 12.0,
'worst_frame_rasterizer_time_millis': 12.0,
'missed_frame_rasterizer_budget_count': 2,
'frame_count': 3,
Expand Down

0 comments on commit 35e8cd8

Please sign in to comment.