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

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

Issue 2339803004: entrypoint to measure performance of the analyzer frontend (Closed)
Patch Set: Created 4 years, 3 months 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 | pkg/analyzer_cli/tool/perf_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// An entrypoint used to run portions of analyzer and measure its performance.
6 library analyzer_cli.tool.perf;
7
8 import 'dart:io' show exit;
9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/token.dart';
11 import 'package:analyzer/file_system/file_system.dart'
12 show ResourceProvider, ResourceUriResolver
13 hide File;
14 import 'package:analyzer/file_system/physical_file_system.dart'
15 show PhysicalResourceProvider;
16 import 'package:analyzer/src/dart/scanner/reader.dart';
17 import 'package:analyzer/src/dart/scanner/scanner.dart';
18 import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
19 import 'package:analyzer/src/error.dart';
20 import 'package:analyzer/src/generated/error.dart';
21 import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
22 import 'package:analyzer/src/generated/parser.dart';
23 import 'package:analyzer/src/generated/source.dart';
24 import 'package:analyzer/src/generated/source_io.dart';
25
26 /// Cummulative total number of chars scanned.
27 int scanTotalChars = 0;
28
29 /// Cummulative time spent scanning.
30 Stopwatch scanTimer = new Stopwatch();
31
32 /// Factory to load and resolve app, packages, and sdk sources.
33 SourceFactory sources;
34
35 main(args) {
36 // TODO(sigmund): provide sdk folder as well.
37 if (args.length < 2) {
38 print('usage: perf.dart <bench-id> <package-root> <entry.dart>');
39 exit(1);
40 }
41 var totalTimer = new Stopwatch()..start();
42
43 var bench = args[0];
44 var packageRoot = args[1];
45 var entryUri = Uri.base.resolve(args[2]);
46
47 setup(packageRoot);
48 if (bench == 'scan') {
49 scanReachableFiles(entryUri);
50 } else if (bench == 'parse') {
51 Set<Source> files = scanReachableFiles(entryUri);
52 parseFiles(files);
53 } else {
54 print('unsupported bench-id: $bench. Please specify "scan" or "parse"');
55 // TODO(sigmund): implement the remaining benchmarks.
56 exit(1);
57 }
58
59 totalTimer.stop();
60 report("Total", totalTimer.elapsedMicroseconds);
61 }
62
63 /// Sets up analyzer to be able to load and resolve app, packages, and sdk
64 /// sources.
65 void setup(String packageRoot) {
66 var provider = PhysicalResourceProvider.INSTANCE;
67 sources = new SourceFactory([
68 new ResourceUriResolver(provider),
69 new PackageUriResolver([new JavaFile(packageRoot)]),
70 new DartUriResolver(
71 new FolderBasedDartSdk(provider, provider.getFolder("sdk"))),
72 ]);
73 }
74
75 /// Load and scans all files we need to process: files reachable from the
76 /// entrypoint and all core libraries automatically included by the VM.
77 Set<Source> scanReachableFiles(Uri entryUri) {
78 var files = new Set<Source>();
79 var loadTimer = new Stopwatch()..start();
80 collectSources(sources.forUri2(entryUri), files);
81 collectSources(sources.forUri("dart:async"), files);
82 collectSources(sources.forUri("dart:collection"), files);
83 collectSources(sources.forUri("dart:convert"), files);
84 collectSources(sources.forUri("dart:core"), files);
85 collectSources(sources.forUri("dart:developer"), files);
86 collectSources(sources.forUri("dart:_internal"), files);
87 collectSources(sources.forUri("dart:isolate"), files);
88 collectSources(sources.forUri("dart:math"), files);
89 collectSources(sources.forUri("dart:mirrors"), files);
90 collectSources(sources.forUri("dart:typed_data"), files);
91 loadTimer.stop();
92
93 print('input size: ${scanTotalChars} chars');
94 var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
95 report("Loader", loadTime);
96 report("Scanner", scanTimer.elapsedMicroseconds);
97 return files;
98 }
99
100 /// Parses every file in [files] and reports the time spent doing so.
101 void parseFiles(Set<Source> files) {
102 // The code below will record again how many chars are scanned and how long it
103 // takes to scan them, even though we already did so in [scanReachableFiles].
104 // Recording and reporting this twice is unnecessary, but we do so for now to
105 // validate that the results are consistent.
106 scanTimer = new Stopwatch();
107 var oldTotal = scanTotalChars;
108 scanTotalChars = 0;
109 var parseTimer = new Stopwatch()..start();
110 for (var source in files) {
111 parseFull(source);
112 }
113 parseTimer.stop();
114
115 // Report size and scanning time again. See discussion above.
116 if (oldTotal != scanTotalChars) print('input size changed? ${total} chars');
117 report("Scanner", scanTimer.elapsedMicroseconds);
118
119 var pTime = parseTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
120 report("Parser", pTime);
121 }
122
123 /// Add to [files] all sources reachable from [start].
124 void collectSources(Source start, Set<Source> files) {
125 if (!files.add(start)) return;
126 var unit = parseDirectives(start);
127 for (var directive in unit.directives) {
128 if (directive is! UriBasedDirective) continue;
129 var next = sources.resolveUri(start, directive.uri.stringValue);
Brian Wilkerson 2016/09/16 15:32:02 This introduces a compilation error: ERROR: The g
130 collectSources(next, files);
131 }
132 }
133
134 /// Uses the diet-parser to parse only directives in [source].
135 CompilationUnit parseDirectives(Source source) {
136 var token = tokenize(source);
137 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
138 return parser.parseDirectives(token);
139 }
140
141 /// Parse the full body of [source] and return it's compilation unit.
142 CompilationUnit parseFull(Source source) {
143 var token = tokenize(source);
144 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
145 return parser.parseCompilationUnit(token);
146 }
147
148 /// Scan [source] and return the first token produced by the scanner.
149 Token tokenize(Source source) {
150 scanTimer.start();
151 var contents = source.contents.data;
152 scanTotalChars += contents.length;
153 // TODO(sigmund): is there a way to scan from a random-access-file without
154 // first converting to String?
155 var scanner = new Scanner(source, new CharSequenceReader(contents),
156 AnalysisErrorListener.NULL_LISTENER);
157 var token = scanner.tokenize();
158 scanTimer.stop();
159 return token;
160 }
161
162 /// Report that metric [name] took [time] micro-seconds to process
163 /// [scanTotalChars] characters.
164 void report(String name, int time) {
165 var sb = new StringBuffer();
166 sb.write('$name: ${time ~/ 1000} ms');
167 sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
168 print('$sb');
169 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer_cli/tool/perf_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698