Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: pkg/front_end/tool/perf.dart

Issue 2556723005: Add a perf test for generating linked summaries. (Closed)
Patch Set: Refactor Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// An entrypoint used to run portions of front_end and measure its performance. 5 /// An entrypoint used to run portions of front_end and measure its performance.
6 library front_end.tool.perf; 6 library front_end.tool.perf;
7 7
8 import 'dart:async'; 8 import 'dart:async';
9 import 'dart:io' show exit, stderr; 9 import 'dart:io' show exit, stderr;
10 10
11 import 'package:analyzer/dart/ast/ast.dart'; 11 import 'package:analyzer/dart/ast/ast.dart';
12 import 'package:analyzer/error/listener.dart'; 12 import 'package:analyzer/error/listener.dart';
13 import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver; 13 import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver;
14 import 'package:analyzer/file_system/physical_file_system.dart' 14 import 'package:analyzer/file_system/physical_file_system.dart'
15 show PhysicalResourceProvider; 15 show PhysicalResourceProvider;
16 import 'package:analyzer/source/package_map_resolver.dart'; 16 import 'package:analyzer/source/package_map_resolver.dart';
17 import 'package:analyzer/src/context/builder.dart'; 17 import 'package:analyzer/src/context/builder.dart';
18 import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk; 18 import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
19 import 'package:analyzer/src/generated/parser.dart'; 19 import 'package:analyzer/src/generated/parser.dart';
20 import 'package:analyzer/src/generated/source.dart'; 20 import 'package:analyzer/src/generated/source.dart';
21 import 'package:analyzer/src/generated/source_io.dart'; 21 import 'package:analyzer/src/generated/source_io.dart';
22 import 'package:analyzer/src/summary/format.dart'; 22 import 'package:analyzer/src/summary/format.dart';
23 import 'package:analyzer/src/summary/idl.dart'; 23 import 'package:analyzer/src/summary/idl.dart';
24 import 'package:analyzer/src/summary/prelink.dart'; 24 import 'package:analyzer/src/summary/link.dart';
25 import 'package:analyzer/src/summary/summarize_ast.dart'; 25 import 'package:analyzer/src/summary/summarize_ast.dart';
26 import 'package:kernel/analyzer/loader.dart'; 26 import 'package:kernel/analyzer/loader.dart';
27 import 'package:kernel/kernel.dart'; 27 import 'package:kernel/kernel.dart';
28 import 'package:package_config/discovery.dart'; 28 import 'package:package_config/discovery.dart';
29 29
30 import 'package:front_end/src/scanner/reader.dart'; 30 import 'package:front_end/src/scanner/reader.dart';
31 import 'package:front_end/src/scanner/scanner.dart'; 31 import 'package:front_end/src/scanner/scanner.dart';
32 import 'package:front_end/src/scanner/token.dart'; 32 import 'package:front_end/src/scanner/token.dart';
33 33
34 /// Cumulative total number of chars scanned. 34 /// Cumulative total number of chars scanned.
35 int scanTotalChars = 0; 35 int scanTotalChars = 0;
36 36
37 /// Cumulative time spent scanning. 37 /// Cumulative time spent scanning.
38 Stopwatch scanTimer = new Stopwatch(); 38 Stopwatch scanTimer = new Stopwatch();
39 39
40 /// Cumulative time spent parsing. 40 /// Cumulative time spent parsing.
41 Stopwatch parseTimer = new Stopwatch(); 41 Stopwatch parseTimer = new Stopwatch();
42 42
43 /// Cumulative time spent building unlinked summaries. 43 /// Cumulative time spent building unlinked summaries.
44 Stopwatch unlinkedSummarizeTimer = new Stopwatch(); 44 Stopwatch unlinkedSummarizeTimer = new Stopwatch();
45 45
46 /// Cumulative time spent prelinking summaries.
47 Stopwatch prelinkSummaryTimer = new Stopwatch();
48
46 /// Factory to load and resolve app, packages, and sdk sources. 49 /// Factory to load and resolve app, packages, and sdk sources.
47 SourceFactory sources; 50 SourceFactory sources;
48 51
49 main(List<String> args) async { 52 main(List<String> args) async {
50 // TODO(sigmund): provide sdk folder as well. 53 // TODO(sigmund): provide sdk folder as well.
51 if (args.length < 2) { 54 if (args.length < 2) {
52 print('usage: perf.dart <bench-id> <entry.dart>'); 55 print('usage: perf.dart <bench-id> <entry.dart>');
53 exit(1); 56 exit(1);
54 } 57 }
55 var totalTimer = new Stopwatch()..start(); 58 var totalTimer = new Stopwatch()..start();
(...skipping 25 matching lines...) Expand all
81 }, 84 },
82 'unlinked_summarize': () async { 85 'unlinked_summarize': () async {
83 Set<Source> files = scanReachableFiles(entryUri); 86 Set<Source> files = scanReachableFiles(entryUri);
84 // TODO(sigmund): replace the warmup with instrumented snapshots. 87 // TODO(sigmund): replace the warmup with instrumented snapshots.
85 for (int i = 0; i < 10; i++) unlinkedSummarizeFiles(files); 88 for (int i = 0; i < 10; i++) unlinkedSummarizeFiles(files);
86 }, 89 },
87 'prelinked_summarize': () async { 90 'prelinked_summarize': () async {
88 Set<Source> files = scanReachableFiles(entryUri); 91 Set<Source> files = scanReachableFiles(entryUri);
89 // TODO(sigmund): replace the warmup with instrumented snapshots. 92 // TODO(sigmund): replace the warmup with instrumented snapshots.
90 for (int i = 0; i < 10; i++) prelinkedSummarizeFiles(files); 93 for (int i = 0; i < 10; i++) prelinkedSummarizeFiles(files);
94 },
95 'linked_summarize': () async {
96 Set<Source> files = scanReachableFiles(entryUri);
97 // TODO(sigmund): replace the warmup with instrumented snapshots.
98 for (int i = 0; i < 10; i++) linkedSummarizeFiles(files);
91 } 99 }
92 }; 100 };
93 101
94 var handler = handlers[bench]; 102 var handler = handlers[bench];
95 if (handler == null) { 103 if (handler == null) {
96 // TODO(sigmund): implement the remaining benchmarks. 104 // TODO(sigmund): implement the remaining benchmarks.
97 print('unsupported bench-id: $bench. Please specify one of the following: ' 105 print('unsupported bench-id: $bench. Please specify one of the following: '
98 '${handlers.keys.join(", ")}'); 106 '${handlers.keys.join(", ")}');
99 exit(1); 107 exit(1);
100 } 108 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 void unlinkedSummarizeFiles(Set<Source> files) { 203 void unlinkedSummarizeFiles(Set<Source> files) {
196 // The code below will record again how many chars are scanned and how long it 204 // The code below will record again how many chars are scanned and how long it
197 // takes to scan them, even though we already did so in [scanReachableFiles]. 205 // takes to scan them, even though we already did so in [scanReachableFiles].
198 // Recording and reporting this twice is unnecessary, but we do so for now to 206 // Recording and reporting this twice is unnecessary, but we do so for now to
199 // validate that the results are consistent. 207 // validate that the results are consistent.
200 scanTimer = new Stopwatch(); 208 scanTimer = new Stopwatch();
201 var old = scanTotalChars; 209 var old = scanTotalChars;
202 scanTotalChars = 0; 210 scanTotalChars = 0;
203 parseTimer = new Stopwatch(); 211 parseTimer = new Stopwatch();
204 unlinkedSummarizeTimer = new Stopwatch(); 212 unlinkedSummarizeTimer = new Stopwatch();
205 for (var source in files) { 213 generateUnlinkedSummaries(files);
206 unlinkedSummarize(source);
207 }
208 214
209 if (old != scanTotalChars) print('input size changed? ${old} chars'); 215 if (old != scanTotalChars) print('input size changed? ${old} chars');
210 report("scan", scanTimer.elapsedMicroseconds); 216 report("scan", scanTimer.elapsedMicroseconds);
211 report("parse", parseTimer.elapsedMicroseconds); 217 report("parse", parseTimer.elapsedMicroseconds);
212 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); 218 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
213 report( 219 report(
214 'unlinked summarize + parse', 220 'unlinked summarize + parse',
215 unlinkedSummarizeTimer.elapsedMicroseconds + 221 unlinkedSummarizeTimer.elapsedMicroseconds +
216 parseTimer.elapsedMicroseconds); 222 parseTimer.elapsedMicroseconds);
217 } 223 }
218 224
225 /// Simple container for a mapping from URI string to an unlinked summary.
226 class UnlinkedSummaries {
227 final summariesByUri = <String, UnlinkedUnit>{};
228
229 /// Get the unlinked summary for the given URI, and report a warning if it
230 /// can't be found.
231 UnlinkedUnit getUnit(String uri) {
232 var result = summariesByUri[uri];
233 if (result == null) {
234 print('Warning: no summary found for: $uri');
235 }
236 return result;
237 }
238 }
239
240 /// Generates unlinkmed summaries for all files in [files], and returns them in
241 /// an [UnlinkedSummaries] container.
242 UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) {
243 var unlinkedSummaries = new UnlinkedSummaries();
244 for (var source in files) {
245 unlinkedSummaries.summariesByUri[source.uri.toString()] =
246 unlinkedSummarize(source);
247 }
248 return unlinkedSummaries;
249 }
250
219 /// Produces prelinked summaries for every file in [files] and reports the time 251 /// Produces prelinked summaries for every file in [files] and reports the time
220 /// spent doing so. 252 /// spent doing so.
221 void prelinkedSummarizeFiles(Set<Source> files) { 253 void prelinkedSummarizeFiles(Set<Source> files) {
222 // The code below will record again how many chars are scanned and how long it 254 // The code below will record again how many chars are scanned and how long it
223 // takes to scan them, even though we already did so in [scanReachableFiles]. 255 // takes to scan them, even though we already did so in [scanReachableFiles].
224 // Recording and reporting this twice is unnecessary, but we do so for now to 256 // Recording and reporting this twice is unnecessary, but we do so for now to
225 // validate that the results are consistent. 257 // validate that the results are consistent.
226 scanTimer = new Stopwatch(); 258 scanTimer = new Stopwatch();
227 var old = scanTotalChars; 259 var old = scanTotalChars;
228 scanTotalChars = 0; 260 scanTotalChars = 0;
229 parseTimer = new Stopwatch(); 261 parseTimer = new Stopwatch();
230 unlinkedSummarizeTimer = new Stopwatch(); 262 unlinkedSummarizeTimer = new Stopwatch();
231 var unlinkedSummaries = <Source, UnlinkedUnit>{}; 263 var unlinkedSummaries = generateUnlinkedSummaries(files);
232 for (var source in files) { 264 prelinkSummaryTimer = new Stopwatch();
233 unlinkedSummaries[source] = unlinkedSummarize(source); 265 prelinkSummaries(files, unlinkedSummaries);
234 }
235 var prelinkTimer = new Stopwatch()..start();
236 for (var source in files) {
237 UnlinkedUnit getSummary(String uri) {
238 var resolvedUri = sources.resolveUri(source, uri);
239 var result = unlinkedSummaries[resolvedUri];
240 if (result == null) {
241 print('Warning: no summary found for: $uri');
242 }
243 return result;
244 }
245
246 UnlinkedPublicNamespace getImport(String uri) =>
247 getSummary(uri)?.publicNamespace;
248 String getDeclaredVariable(String s) => null;
249 prelink(
250 unlinkedSummaries[source], getSummary, getImport, getDeclaredVariable);
251 }
252 prelinkTimer.stop();
253 266
254 if (old != scanTotalChars) print('input size changed? ${old} chars'); 267 if (old != scanTotalChars) print('input size changed? ${old} chars');
255 report("scan", scanTimer.elapsedMicroseconds); 268 report("scan", scanTimer.elapsedMicroseconds);
269 report("parse", parseTimer.elapsedMicroseconds);
270 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
271 report(
272 'unlinked summarize + parse',
273 unlinkedSummarizeTimer.elapsedMicroseconds +
274 parseTimer.elapsedMicroseconds);
275 report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
276 }
277
278 /// Produces linked summaries for every file in [files] and reports the time
279 /// spent doing so.
280 void linkedSummarizeFiles(Set<Source> files) {
281 // The code below will record again how many chars are scanned and how long it
282 // takes to scan them, even though we already did so in [scanReachableFiles].
283 // Recording and reporting this twice is unnecessary, but we do so for now to
284 // validate that the results are consistent.
285 scanTimer = new Stopwatch();
286 var old = scanTotalChars;
287 scanTotalChars = 0;
288 parseTimer = new Stopwatch();
289 unlinkedSummarizeTimer = new Stopwatch();
290 var unlinkedSummaries = generateUnlinkedSummaries(files);
291 prelinkSummaryTimer = new Stopwatch();
292 Map<String, LinkedLibraryBuilder> prelinkedLibraries =
293 prelinkSummaries(files, unlinkedSummaries);
294 var linkTimer = new Stopwatch()..start();
295 LinkedLibrary getDependency(String uri) {
296 // getDependency should never be called because all dependencies are present
297 // in [prelinkedLibraries].
298 print('Warning: getDependency called for: $uri');
299 return null;
300 }
301
302 bool strong = true;
303 relink(prelinkedLibraries, getDependency, unlinkedSummaries.getUnit, strong);
304 linkTimer.stop();
305
306 if (old != scanTotalChars) print('input size changed? ${old} chars');
307 report("scan", scanTimer.elapsedMicroseconds);
256 report("parse", parseTimer.elapsedMicroseconds); 308 report("parse", parseTimer.elapsedMicroseconds);
257 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); 309 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
258 report( 310 report(
259 'unlinked summarize + parse', 311 'unlinked summarize + parse',
260 unlinkedSummarizeTimer.elapsedMicroseconds + 312 unlinkedSummarizeTimer.elapsedMicroseconds +
261 parseTimer.elapsedMicroseconds); 313 parseTimer.elapsedMicroseconds);
262 report('prelink', prelinkTimer.elapsedMicroseconds); 314 report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
315 report('link', linkTimer.elapsedMicroseconds);
316 }
317
318 /// Prelinks all the summaries for [files], using [unlinkedSummaries] to obtain
319 /// their unlinked summaries.
320 ///
321 /// The return value is suitable for passing to the summary linker.
322 Map<String, LinkedLibraryBuilder> prelinkSummaries(
323 Set<Source> files, UnlinkedSummaries unlinkedSummaries) {
324 prelinkSummaryTimer.start();
325 Set<String> libraryUris =
326 files.map((source) => source.uri.toString()).toSet();
327
328 String getDeclaredVariable(String s) => null;
329 var prelinkedLibraries =
330 setupForLink(libraryUris, unlinkedSummaries.getUnit, getDeclaredVariable);
331 prelinkSummaryTimer.stop();
332 return prelinkedLibraries;
263 } 333 }
264 334
265 /// Add to [files] all sources reachable from [start]. 335 /// Add to [files] all sources reachable from [start].
266 void collectSources(Source start, Set<Source> files) { 336 void collectSources(Source start, Set<Source> files) {
267 if (!files.add(start)) return; 337 if (!files.add(start)) return;
268 var unit = parseDirectives(start); 338 var unit = parseDirectives(start);
269 for (var directive in unit.directives) { 339 for (var directive in unit.directives) {
270 if (directive is UriBasedDirective) { 340 if (directive is UriBasedDirective) {
271 var next = sources.resolveUri(start, directive.uri.stringValue); 341 var next = sources.resolveUri(start, directive.uri.stringValue);
272 collectSources(next, files); 342 collectSources(next, files);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 const int errorLimit = 100; 417 const int errorLimit = 100;
348 stderr.writeln(errors.take(errorLimit).join('\n')); 418 stderr.writeln(errors.take(errorLimit).join('\n'));
349 if (errors.length > errorLimit) { 419 if (errors.length > errorLimit) {
350 stderr.writeln('[error] ${errors.length - errorLimit} errors not shown'); 420 stderr.writeln('[error] ${errors.length - errorLimit} errors not shown');
351 } 421 }
352 } 422 }
353 dartkTimer.stop(); 423 dartkTimer.stop();
354 report("kernel_gen_e2e", dartkTimer.elapsedMicroseconds); 424 report("kernel_gen_e2e", dartkTimer.elapsedMicroseconds);
355 return program; 425 return program;
356 } 426 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698