Skip to content

Commit

Permalink
Add more data to each perf run
Browse files Browse the repository at this point in the history
  • Loading branch information
filiph committed Apr 9, 2019
1 parent 9ff5e24 commit e1ff7d3
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 76 deletions.
133 changes: 133 additions & 0 deletions test_driver/parse_timeline.dart
@@ -0,0 +1,133 @@
import 'dart:convert';
import 'dart:io';

import 'package:flutter_driver/flutter_driver.dart'
show Timeline, TimelineSummary;

Future<int> main(List<String> args) async {
if (args.length != 1) {
stderr.writeln('Usage: dart tool/parse_timeline.dart [FILE]');
return 2;
}

print("Running on file: ${args.single}");

var file = File(args.single);
var contents = await file.readAsString();
var map = json.decode(contents) as Map<String, Object>;
var timeline = Timeline.fromJson(map);
var summary = TimelineSummary.summarize(timeline);

var results = parse(timeline, summary);

print('RunExpiredTasks events: ${results.expiredTasksEvents}');
print('RunExpiredTasks duration: ${results.expiredTasksDuration}');

print('Dart thread events: ${results.dartPhaseEvents}');
print('Dart thread duration: ${results.dartPhaseDuration}');

var lengthMicros = timeline.json['timeExtentMicros'] as int;
var lengthSeconds = lengthMicros / Duration.microsecondsPerSecond;
var frames = summary.countFrames();
var fps = frames / lengthSeconds;

print('Length: ${lengthSeconds}s');
print('Frames: $frames');
print('Average FPS: $fps');

print('Dart percentage: ${results.dartPercentage.toStringAsPrecision(5)}');

return 0;
}

AdditionalResults parse(Timeline timeline, TimelineSummary summary) {
var dartPhaseEvents = 0;
var dartPhaseDuration = Duration.zero;
int expiredTasksEvents = 0;
var durationMicros = 0;
// Previous events per each thread.
Map<int, int> prevs = {};

for (final ev in timeline.events) {
if (ev.phase == 'X' && ev.category == 'Dart') {
// Dart thread event with duration.
dartPhaseEvents += 1;
dartPhaseDuration += ev.threadDuration;
}

if (ev.name != 'MessageLoop::RunExpiredTasks') continue;

var tid = ev.threadId;
assert(tid != null);

if (ev.phase == 'B') {
if (prevs.containsKey(tid)) {
// print("there is already an event on this same thread");
}
prevs[tid] = ev.timestampMicros;
continue;
}

if (ev.phase == 'E') {
if (!prevs.containsKey(tid)) {
// print("ending tid $tid that has no beginning,"
// "ts: ${ev.timestampMicros}");
continue;
}
durationMicros += ev.timestampMicros - prevs[tid];
prevs.remove(tid);
expiredTasksEvents++;
continue;
}

assert(false);
}

var expiredTasksDuration = Duration(microseconds: durationMicros);

var lengthMicros = timeline.json['timeExtentMicros'] as int;
var lengthSeconds = lengthMicros / Duration.microsecondsPerSecond;
var frames = summary.countFrames();
var fps = frames / lengthSeconds;
var dartPercentage = dartPhaseDuration.inMicroseconds / lengthMicros;

return AdditionalResults(
Duration(microseconds: lengthMicros),
frames,
fps,
dartPhaseEvents,
dartPhaseDuration,
expiredTasksEvents,
expiredTasksDuration,
dartPercentage,
);
}

class AdditionalResults {
final int dartPhaseEvents;

final Duration dartPhaseDuration;

final int expiredTasksEvents;

final Duration expiredTasksDuration;

final Duration length;

final int frames;

final double fps;

/// Percentage of thread time spent in Dart.
final double dartPercentage;

const AdditionalResults(
this.length,
this.frames,
this.fps,
this.dartPhaseEvents,
this.dartPhaseDuration,
this.expiredTasksEvents,
this.expiredTasksDuration,
this.dartPercentage);
}
3 changes: 1 addition & 2 deletions test_driver/perf_stats.tsv
@@ -1,2 +1 @@
name mean lowerBound upperBound marginOfError stdDeviation stdError min max n 90thPercentile 99thPercentile worstFrame missedFrames

name mean lowerBound upperBound marginOfError stdDeviation stdError min max n description 90thPercentile 99thPercentile worstFrame missedFrames length frames fps dartPercentage dartPhaseEvents dartPhaseDuration expiredTasksEvents expiredTasksDuration
36 changes: 29 additions & 7 deletions test_driver/performance_test.dart
Expand Up @@ -5,13 +5,15 @@ import 'package:flutter_driver/flutter_driver.dart';
import 'package:git/git.dart';
import 'package:t_stats/t_stats.dart';

import 'parse_timeline.dart';

Future<void> main(List<String> args) async {
FlutterDriver driver;

try {
driver = await FlutterDriver.connect();
var summary = await _run(driver);
await _save(summary);
var timeline = await _run(driver);
await _save(timeline);
} finally {
if (driver != null) {
await driver.close();
Expand Down Expand Up @@ -51,7 +53,7 @@ Future _completeTask(FlutterDriver driver, String taskName) async {
await driver.tap(shipIt);
}

Future<TimelineSummary> _run(FlutterDriver driver) async {
Future<Timeline> _run(FlutterDriver driver) async {
var health = await driver.checkHealth();
if (health.status != HealthStatus.ok) {
throw StateError('FlutterDriver health: $health');
Expand All @@ -71,12 +73,10 @@ Future<TimelineSummary> _run(FlutterDriver driver) async {
await _completeTask(driver, 'Programmer Art UI');
await _completeTask(driver, 'Alpha release');

var timeline = await driver.stopTracingAndDownloadTimeline();

return TimelineSummary.summarize(timeline);
return driver.stopTracingAndDownloadTimeline();
}

Future<void> _save(TimelineSummary summary) async {
Future<void> _save(Timeline timeline) async {
var description = Platform.environment['DESC'];

if (description == null) {
Expand All @@ -99,6 +99,8 @@ Future<void> _save(TimelineSummary summary) async {
var id = 'performance_test-${now.toIso8601String()}';
var filename = id.replaceAll(':', '-');

var summary = TimelineSummary.summarize(timeline);

await summary.writeSummaryToFile(filename, pretty: true);
await summary.writeTimelineToFile(filename);

Expand All @@ -110,20 +112,40 @@ Future<void> _save(TimelineSummary summary) async {
name: id,
);

var additional = parse(timeline, summary);

IOSink stats;
try {
stats = File('test_driver/perf_stats.tsv').openWrite(mode: FileMode.append);
// Add general build time statistics.
stats.write(buildTimesStat.toTSV());
// Add additional useful stats from the TimelineSummary.
stats.write('\t');
stats.write(description);
stats.write('\t');
stats.write(summary.computePercentileFrameBuildTimeMillis(90.0));
stats.write('\t');
stats.write(summary.computePercentileFrameBuildTimeMillis(99.0));
stats.write('\t');
stats.write(summary.computeWorstFrameBuildTimeMillis());
stats.write('\t');
stats.write(summary.computeMissedFrameBuildBudgetCount());
stats.write('\t');
stats.write(additional.length.inMicroseconds);
stats.write('\t');
stats.write(additional.frames);
stats.write('\t');
stats.write(additional.fps);
stats.write('\t');
stats.write(additional.dartPercentage);
stats.write('\t');
stats.write(additional.dartPhaseEvents);
stats.write('\t');
stats.write(additional.dartPhaseDuration.inMicroseconds);
stats.write('\t');
stats.write(additional.expiredTasksEvents);
stats.write('\t');
stats.write(additional.expiredTasksDuration.inMicroseconds);
stats.writeln();
} finally {
await stats?.close();
Expand Down
67 changes: 0 additions & 67 deletions tool/parse_timeline.dart

This file was deleted.

0 comments on commit e1ff7d3

Please sign in to comment.