blob: 19c6e6c16158d34df37e058e32fed6f878a7a0c5 [file] [log] [blame]
// 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) {
} else {
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) {
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}";