// Copyright (c) 2016 The Chromium 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 'dart:io'; import 'package:path/path.dart' as path; import '../framework/framework.dart'; import '../framework/utils.dart'; /// Run each benchmark this many times and compute average. const int _kRunsPerBenchmark = 3; /// Runs a benchmark once and reports the result as a lower-is-better numeric /// value. typedef Future<double> _Benchmark(); /// Path to the generated "mega gallery" app. Directory get _megaGalleryDirectory => dir(path.join(Directory.systemTemp.path, 'mega_gallery')); Future<TaskResult> analyzerBenchmarkTask() async { await inDirectory(flutterDirectory, () async { rmTree(_megaGalleryDirectory); mkdirs(_megaGalleryDirectory); await dart(<String>['dev/tools/mega_gallery.dart', '--out=${_megaGalleryDirectory.path}']); }); final Map<String, dynamic> data = <String, dynamic>{ 'flutter_repo_batch': await _run(new _FlutterRepoBenchmark()), 'flutter_repo_watch': await _run(new _FlutterRepoBenchmark(watch: true)), 'mega_gallery_batch': await _run(new _MegaGalleryBenchmark()), 'mega_gallery_watch': await _run(new _MegaGalleryBenchmark(watch: true)), }; return new TaskResult.success(data, benchmarkScoreKeys: data.keys.toList()); } /// Times how long it takes to analyze the Flutter repository. class _FlutterRepoBenchmark { _FlutterRepoBenchmark({ this.watch = false }); final bool watch; Future<double> call() async { section('Analyze Flutter repo ${watch ? 'with watcher' : ''}'); final Stopwatch stopwatch = new Stopwatch(); await inDirectory(flutterDirectory, () async { final List<String> options = <String>[ '--flutter-repo', '--benchmark', ]; if (watch) options.add('--watch'); stopwatch.start(); await flutter('analyze', options: options); stopwatch.stop(); }); return stopwatch.elapsedMilliseconds / 1000; } } /// Times how long it takes to analyze the generated "mega_gallery" app. class _MegaGalleryBenchmark { _MegaGalleryBenchmark({ this.watch = false }); final bool watch; Future<double> call() async { section('Analyze mega gallery ${watch ? 'with watcher' : ''}'); final Stopwatch stopwatch = new Stopwatch(); await inDirectory(_megaGalleryDirectory, () async { final List<String> options = <String>[ '--benchmark', ]; if (watch) options.add('--watch'); stopwatch.start(); await flutter('analyze', options: options); stopwatch.stop(); }); return stopwatch.elapsedMilliseconds / 1000; } } /// Runs a [benchmark] several times and reports the average result. Future<double> _run(_Benchmark benchmark) async { double total = 0.0; for (int i = 0; i < _kRunsPerBenchmark; i++) { // Delete cached analysis results. rmTree(dir('${Platform.environment['HOME']}/.dartServer')); total += await benchmark(); } final double average = total / _kRunsPerBenchmark; return average; }