| // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| library protoc.benchmark.vm; |
| |
| import 'dart:async' show Future; |
| import 'dart:io' show File, Directory, Link, Platform, stdout; |
| |
| import '../data/index.dart' |
| show latestVMReportName, pubspecYamlName, pubspecLockName, hostfileName; |
| import 'benchmarks/index.dart' show createBenchmark; |
| import 'generated/benchmark.pb.dart' as pb; |
| import 'report.dart' |
| show createPlatform, createPackages, encodeReport, findUpdatedResponse; |
| import 'suite.dart' show runSuite; |
| |
| /// Runs a benchmark suite. |
| /// Writes a report to latest_vm.pb.json after every change, |
| /// to make progress available to the browser. |
| runSuiteInVM(pb.Suite suite) async { |
| var env = await _loadEnv(); |
| |
| pb.Report lastReport; |
| pb.Response lastUpdate; |
| for (var report in runSuite(suite.requests, samplesPerBatch: 10)) { |
| report.env = env; |
| |
| // show progress |
| var update = findUpdatedResponse(lastReport, report); |
| if (update != null) { |
| var summary = _summarize(update); |
| if (lastUpdate == null || update.request != lastUpdate.request) { |
| stdout.write("\n$summary"); |
| } else { |
| _overwrite(summary); |
| } |
| } |
| |
| lastReport = report; |
| lastUpdate = update; |
| } |
| |
| // save the report to a file |
| var outFile = "${dataDir.path}/$latestVMReportName"; |
| var tmpFile = new File("$outFile.tmp"); |
| await tmpFile.writeAsString(encodeReport(lastReport)); |
| await tmpFile.rename(outFile); |
| print("\nWrote result to benchmark/data/${latestVMReportName}"); |
| } |
| |
| String _summarize(pb.Response r) { |
| assert(r != null); |
| var b = createBenchmark(r.request); |
| return b.summarizeResponse(r); |
| } |
| |
| final _escapeChar = new String.fromCharCode(27); |
| final _clearLine = "\r$_escapeChar[2K"; |
| |
| /// Overwrite the last line printed to the terminal. |
| void _overwrite(String line) { |
| stdout.write("$_clearLine$line"); |
| } |
| |
| Future<pb.Env> _loadEnv() async { |
| await _ensureDataDir(); |
| |
| var platform = createPlatform() |
| ..hostname = _hostname |
| ..osType = _osType |
| ..dartVersion = Platform.version; |
| |
| var pubspec = await (new File(pubspecYaml.path).readAsString()); |
| var lock = await (new File(pubspecLock.path).readAsString()); |
| |
| return new pb.Env() |
| ..script = _script |
| ..platform = platform |
| ..packages = createPackages(pubspec, lock); |
| } |
| |
| /// Create files and symlinks in the data directory. |
| /// |
| /// This is so they can be accessed in browser benchmarks. |
| _ensureDataDir() async { |
| await hostnameFile.writeAsString(_hostname); |
| |
| if (!await pubspecYaml.exists()) { |
| await pubspecYaml.create("${pubspecDir.path}/pubspec.yaml"); |
| } |
| |
| if (!await pubspecLock.exists()) { |
| await pubspecLock.create("${pubspecDir.path}/pubspec.lock"); |
| } |
| } |
| |
| String get _script { |
| // Only including the last part of the script name. |
| return Platform.script.pathSegments.last; |
| } |
| |
| String get _hostname { |
| // Only including the first part of the hostname. |
| var h = Platform.localHostname; |
| int firstDot = h.indexOf("."); |
| if (firstDot == -1) return h; |
| return h.substring(0, firstDot); |
| } |
| |
| pb.OSType get _osType { |
| if (Platform.isLinux) return pb.OSType.LINUX; |
| if (Platform.isMacOS) return pb.OSType.MAC; |
| if (Platform.isWindows) return pb.OSType.WINDOWS; |
| if (Platform.isAndroid) return pb.OSType.ANDROID; |
| |
| // What is this? |
| throw "unknown OS type"; |
| } |
| |
| final File hostnameFile = new File("${dataDir.path}/$hostfileName"); |
| final Link pubspecYaml = new Link("${dataDir.path}/$pubspecYamlName"); |
| final Link pubspecLock = new Link("${dataDir.path}/$pubspecLockName"); |
| |
| final Directory dataDir = () { |
| var d = new Directory("${pubspecDir.path}/benchmark/data"); |
| if (!d.existsSync()) { |
| throw "data dir doesn't exist at ${d.path}"; |
| } |
| return d; |
| }(); |
| |
| /// Returns the drectory containing the pubspec.yaml file. |
| final Directory pubspecDir = () { |
| for (var d = Directory.current; d.parent != d; d = d.parent) { |
| if (new File("${d.path}/pubspec.yaml").existsSync()) { |
| return d; |
| } |
| } |
| throw "can't find pubspec.yaml above ${Directory.current}"; |
| }(); |