mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:26:38 +00:00
[benchmarks] Add benchmark to record various startup durations.
TEST=ci Change-Id: I65b298aa3f4a1ddf7752dc787e0a2ff1c2cacff8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241840 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
a5cd295831
commit
6cea65bab7
85
benchmarks/Startup/dart/Startup.dart
Normal file
85
benchmarks/Startup/dart/Startup.dart
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright (c) 2022, 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.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:compiler/src/dart2js.dart' as dart2js;
|
||||||
|
|
||||||
|
Future<void> main(List<String> args) async {
|
||||||
|
if (args.contains('--child')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include dart2js and prevent tree-shaking to make this program have a
|
||||||
|
// non-trival snapshot size.
|
||||||
|
if (args.contains('--train')) {
|
||||||
|
args.remove('--train');
|
||||||
|
return dart2js.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempDir;
|
||||||
|
var events;
|
||||||
|
try {
|
||||||
|
tempDir = await Directory.systemTemp.createTemp();
|
||||||
|
final timelinePath =
|
||||||
|
tempDir.uri.resolve('Startup-timeline.json').toFilePath();
|
||||||
|
final p = await Process.run(Platform.executable, [
|
||||||
|
...Platform.executableArguments,
|
||||||
|
'--timeline_recorder=file:$timelinePath',
|
||||||
|
'--timeline_streams=VM,Isolate,Embedder',
|
||||||
|
Platform.script.toFilePath(),
|
||||||
|
'--child'
|
||||||
|
]);
|
||||||
|
if (p.exitCode != 0) {
|
||||||
|
print(p.stdout);
|
||||||
|
print(p.stderr);
|
||||||
|
throw 'Child process failed: ${p.exitCode}';
|
||||||
|
}
|
||||||
|
|
||||||
|
events = jsonDecode(await File(timelinePath).readAsString());
|
||||||
|
} finally {
|
||||||
|
await tempDir.delete(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var mainIsolateId;
|
||||||
|
for (final event in events) {
|
||||||
|
if (event['name'] == 'InitializeIsolate' &&
|
||||||
|
event['args']['isolateName'] == 'main') {
|
||||||
|
mainIsolateId = event['args']['isolateId'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mainIsolateId == null) {
|
||||||
|
throw 'Could not determine main isolate';
|
||||||
|
}
|
||||||
|
|
||||||
|
void report(String name, String isolateId) {
|
||||||
|
var filtered = events.where((event) => event['name'] == name);
|
||||||
|
if (isolateId != null) {
|
||||||
|
filtered =
|
||||||
|
filtered.where((event) => event['args']['isolateId'] == isolateId);
|
||||||
|
}
|
||||||
|
var micros;
|
||||||
|
final durations = filtered.where((event) => event['ph'] == 'X');
|
||||||
|
final begins = filtered.where((event) => event['ph'] == 'B');
|
||||||
|
final ends = filtered.where((event) => event['ph'] == 'E');
|
||||||
|
if (durations.length == 1 && begins.length == 0 && ends.length == 0) {
|
||||||
|
micros = durations.single['dur'];
|
||||||
|
} else if (durations.length == 0 &&
|
||||||
|
begins.length == 1 &&
|
||||||
|
ends.length == 1) {
|
||||||
|
micros = ends.single['ts'] - begins.single['ts'];
|
||||||
|
} else {
|
||||||
|
print(durations.toList());
|
||||||
|
print(begins.toList());
|
||||||
|
print(ends.toList());
|
||||||
|
throw '$name is missing or ambiguous';
|
||||||
|
}
|
||||||
|
print('Startup.$name(RunTime): $micros us.');
|
||||||
|
}
|
||||||
|
|
||||||
|
report('CreateIsolateGroupAndSetupHelper', null);
|
||||||
|
report('InitializeIsolate', mainIsolateId);
|
||||||
|
report('ReadProgramSnapshot', mainIsolateId);
|
||||||
|
}
|
87
benchmarks/Startup/dart2/Startup.dart
Normal file
87
benchmarks/Startup/dart2/Startup.dart
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright (c) 2022, 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.
|
||||||
|
|
||||||
|
// @dart=2.9
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:compiler/src/dart2js.dart' as dart2js;
|
||||||
|
|
||||||
|
Future<void> main(List<String> args) async {
|
||||||
|
if (args.contains('--child')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include dart2js and prevent tree-shaking to make this program have a
|
||||||
|
// non-trival snapshot size.
|
||||||
|
if (args.contains('--train')) {
|
||||||
|
args.remove('--train');
|
||||||
|
return dart2js.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempDir;
|
||||||
|
var events;
|
||||||
|
try {
|
||||||
|
tempDir = await Directory.systemTemp.createTemp();
|
||||||
|
final timelinePath =
|
||||||
|
tempDir.uri.resolve('Startup-timeline.json').toFilePath();
|
||||||
|
final p = await Process.run(Platform.executable, [
|
||||||
|
...Platform.executableArguments,
|
||||||
|
'--timeline_recorder=file:$timelinePath',
|
||||||
|
'--timeline_streams=VM,Isolate,Embedder',
|
||||||
|
Platform.script.toFilePath(),
|
||||||
|
'--child'
|
||||||
|
]);
|
||||||
|
if (p.exitCode != 0) {
|
||||||
|
print(p.stdout);
|
||||||
|
print(p.stderr);
|
||||||
|
throw 'Child process failed: ${p.exitCode}';
|
||||||
|
}
|
||||||
|
|
||||||
|
events = jsonDecode(await File(timelinePath).readAsString());
|
||||||
|
} finally {
|
||||||
|
await tempDir.delete(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var mainIsolateId;
|
||||||
|
for (final event in events) {
|
||||||
|
if (event['name'] == 'InitializeIsolate' &&
|
||||||
|
event['args']['isolateName'] == 'main') {
|
||||||
|
mainIsolateId = event['args']['isolateId'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mainIsolateId == null) {
|
||||||
|
throw 'Could not determine main isolate';
|
||||||
|
}
|
||||||
|
|
||||||
|
void report(String name, String isolateId) {
|
||||||
|
var filtered = events.where((event) => event['name'] == name);
|
||||||
|
if (isolateId != null) {
|
||||||
|
filtered =
|
||||||
|
filtered.where((event) => event['args']['isolateId'] == isolateId);
|
||||||
|
}
|
||||||
|
var micros;
|
||||||
|
final durations = filtered.where((event) => event['ph'] == 'X');
|
||||||
|
final begins = filtered.where((event) => event['ph'] == 'B');
|
||||||
|
final ends = filtered.where((event) => event['ph'] == 'E');
|
||||||
|
if (durations.length == 1 && begins.length == 0 && ends.length == 0) {
|
||||||
|
micros = durations.single['dur'];
|
||||||
|
} else if (durations.length == 0 &&
|
||||||
|
begins.length == 1 &&
|
||||||
|
ends.length == 1) {
|
||||||
|
micros = ends.single['ts'] - begins.single['ts'];
|
||||||
|
} else {
|
||||||
|
print(durations.toList());
|
||||||
|
print(begins.toList());
|
||||||
|
print(ends.toList());
|
||||||
|
throw '$name is missing or ambiguous';
|
||||||
|
}
|
||||||
|
print('Startup.$name(RunTime): $micros us.');
|
||||||
|
}
|
||||||
|
|
||||||
|
report('CreateIsolateGroupAndSetupHelper', null);
|
||||||
|
report('InitializeIsolate', mainIsolateId);
|
||||||
|
report('ReadProgramSnapshot', mainIsolateId);
|
||||||
|
}
|
|
@ -8199,7 +8199,6 @@ void Deserializer::Deserialize(DeserializationRoots* roots) {
|
||||||
TIMELINE_DURATION(thread(), Isolate, "ReadAlloc");
|
TIMELINE_DURATION(thread(), Isolate, "ReadAlloc");
|
||||||
for (intptr_t i = 0; i < num_clusters_; i++) {
|
for (intptr_t i = 0; i < num_clusters_; i++) {
|
||||||
clusters_[i] = ReadCluster();
|
clusters_[i] = ReadCluster();
|
||||||
TIMELINE_DURATION(thread(), Isolate, clusters_[i]->name());
|
|
||||||
clusters_[i]->ReadAlloc(this);
|
clusters_[i]->ReadAlloc(this);
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
intptr_t serializers_next_ref_index_ = Read<int32_t>();
|
intptr_t serializers_next_ref_index_ = Read<int32_t>();
|
||||||
|
@ -8215,7 +8214,6 @@ void Deserializer::Deserialize(DeserializationRoots* roots) {
|
||||||
TIMELINE_DURATION(thread(), Isolate, "ReadFill");
|
TIMELINE_DURATION(thread(), Isolate, "ReadFill");
|
||||||
SafepointWriteRwLocker ml(thread(), isolate_group()->program_lock());
|
SafepointWriteRwLocker ml(thread(), isolate_group()->program_lock());
|
||||||
for (intptr_t i = 0; i < num_clusters_; i++) {
|
for (intptr_t i = 0; i < num_clusters_; i++) {
|
||||||
TIMELINE_DURATION(thread(), Isolate, clusters_[i]->name());
|
|
||||||
clusters_[i]->ReadFill(this, primary);
|
clusters_[i]->ReadFill(this, primary);
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
int32_t section_marker = Read<int32_t>();
|
int32_t section_marker = Read<int32_t>();
|
||||||
|
@ -8247,7 +8245,6 @@ void Deserializer::Deserialize(DeserializationRoots* roots) {
|
||||||
{
|
{
|
||||||
TIMELINE_DURATION(thread(), Isolate, "PostLoad");
|
TIMELINE_DURATION(thread(), Isolate, "PostLoad");
|
||||||
for (intptr_t i = 0; i < num_clusters_; i++) {
|
for (intptr_t i = 0; i < num_clusters_; i++) {
|
||||||
TIMELINE_DURATION(thread(), Isolate, clusters_[i]->name());
|
|
||||||
clusters_[i]->PostLoad(this, refs, primary);
|
clusters_[i]->PostLoad(this, refs, primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue