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

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

Issue 2933753002: Run the sorter to reduce code churn (Closed)
Patch Set: Created 3 years, 6 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 | « pkg/analyzer_cli/test/utils.dart ('k') | 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 analyzer and measure its performance. 5 /// An entrypoint used to run portions of analyzer and measure its performance.
6 library analyzer_cli.tool.perf; 6 library analyzer_cli.tool.perf;
7 7
8 import 'dart:async'; 8 import 'dart:async';
9 import 'dart:io' show exit; 9 import 'dart:io' show exit;
10 10
11 import 'package:analyzer/dart/ast/ast.dart'; 11 import 'package:analyzer/dart/ast/ast.dart';
12 import 'package:analyzer/dart/ast/token.dart'; 12 import 'package:analyzer/dart/ast/token.dart';
13 import 'package:analyzer/error/listener.dart'; 13 import 'package:analyzer/error/listener.dart';
14 import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver; 14 import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver;
15 import 'package:analyzer/file_system/physical_file_system.dart' 15 import 'package:analyzer/file_system/physical_file_system.dart'
16 show PhysicalResourceProvider; 16 show PhysicalResourceProvider;
17 import 'package:analyzer/source/package_map_resolver.dart'; 17 import 'package:analyzer/source/package_map_resolver.dart';
18 import 'package:analyzer/src/context/builder.dart'; 18 import 'package:analyzer/src/context/builder.dart';
19 import 'package:analyzer/src/dart/scanner/reader.dart'; 19 import 'package:analyzer/src/dart/scanner/reader.dart';
20 import 'package:analyzer/src/dart/scanner/scanner.dart'; 20 import 'package:analyzer/src/dart/scanner/scanner.dart';
21 import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk; 21 import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
22 import 'package:analyzer/src/generated/parser.dart'; 22 import 'package:analyzer/src/generated/parser.dart';
23 import 'package:analyzer/src/generated/source.dart'; 23 import 'package:analyzer/src/generated/source.dart';
24 import 'package:analyzer/src/generated/source_io.dart'; 24 import 'package:analyzer/src/generated/source_io.dart';
25 import 'package:package_config/discovery.dart'; 25 import 'package:package_config/discovery.dart';
26 26
27 /// Cumulative total number of chars scanned.
28 int scanTotalChars = 0;
29
30 /// Cumulative time spent scanning.
31 Stopwatch scanTimer = new Stopwatch();
32
33 /// Factory to load and resolve app, packages, and sdk sources.
34 SourceFactory sources;
35
36 main(List<String> args) async { 27 main(List<String> args) async {
37 // TODO(sigmund): provide sdk folder as well. 28 // TODO(sigmund): provide sdk folder as well.
38 if (args.length < 2) { 29 if (args.length < 2) {
39 print('usage: perf.dart <bench-id> <entry.dart>'); 30 print('usage: perf.dart <bench-id> <entry.dart>');
40 exit(1); 31 exit(1);
41 } 32 }
42 var totalTimer = new Stopwatch()..start(); 33 var totalTimer = new Stopwatch()..start();
43 34
44 var bench = args[0]; 35 var bench = args[0];
45 var entryUri = Uri.base.resolve(args[1]); 36 var entryUri = Uri.base.resolve(args[1]);
(...skipping 11 matching lines...) Expand all
57 } else { 48 } else {
58 print('unsupported bench-id: $bench. Please specify "scan" or "parse"'); 49 print('unsupported bench-id: $bench. Please specify "scan" or "parse"');
59 // TODO(sigmund): implement the remaining benchmarks. 50 // TODO(sigmund): implement the remaining benchmarks.
60 exit(1); 51 exit(1);
61 } 52 }
62 53
63 totalTimer.stop(); 54 totalTimer.stop();
64 report("total", totalTimer.elapsedMicroseconds); 55 report("total", totalTimer.elapsedMicroseconds);
65 } 56 }
66 57
67 /// Sets up analyzer to be able to load and resolve app, packages, and sdk 58 /// Cumulative time spent scanning.
68 /// sources. 59 Stopwatch scanTimer = new Stopwatch();
69 Future setup(Uri entryUri) async { 60
70 var provider = PhysicalResourceProvider.INSTANCE; 61 /// Cumulative total number of chars scanned.
71 var packageMap = new ContextBuilder(provider, null, null) 62 int scanTotalChars = 0;
72 .convertPackagesToMap(await findPackages(entryUri)); 63
73 sources = new SourceFactory([ 64 /// Factory to load and resolve app, packages, and sdk sources.
74 new ResourceUriResolver(provider), 65 SourceFactory sources;
75 new PackageMapUriResolver(provider, packageMap), 66
76 new DartUriResolver( 67 /// Add to [files] all sources reachable from [start].
77 new FolderBasedDartSdk(provider, provider.getFolder("sdk"))), 68 void collectSources(Source start, Set<Source> files) {
78 ]); 69 if (!files.add(start)) return;
70 var unit = parseDirectives(start);
71 for (var directive in unit.directives) {
72 if (directive is UriBasedDirective) {
73 var next = sources.resolveUri(start, directive.uri.stringValue);
74 collectSources(next, files);
75 }
76 }
79 } 77 }
80 78
81 /// Load and scans all files we need to process: files reachable from the 79 /// Uses the diet-parser to parse only directives in [source].
82 /// entrypoint and all core libraries automatically included by the VM. 80 CompilationUnit parseDirectives(Source source) {
83 Set<Source> scanReachableFiles(Uri entryUri) { 81 var token = tokenize(source);
84 var files = new Set<Source>(); 82 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
85 var loadTimer = new Stopwatch()..start(); 83 return parser.parseDirectives(token);
86 collectSources(sources.forUri2(entryUri), files);
87
88 var libs = [
89 "dart:async",
90 "dart:collection",
91 "dart:convert",
92 "dart:core",
93 "dart:developer",
94 "dart:_internal",
95 "dart:isolate",
96 "dart:math",
97 "dart:mirrors",
98 "dart:typed_data",
99 "dart:io"
100 ];
101
102 for (var lib in libs) {
103 collectSources(sources.forUri(lib), files);
104 }
105
106 loadTimer.stop();
107
108 print('input size: ${scanTotalChars} chars');
109 var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
110 report("load", loadTime);
111 report("scan", scanTimer.elapsedMicroseconds);
112 return files;
113 } 84 }
114 85
115 /// Scans every file in [files] and reports the time spent doing so. 86 /// Parses every file in [files] and reports the time spent doing so.
116 void scanFiles(Set<Source> files) { 87 void parseFiles(Set<Source> files) {
117 // The code below will record again how many chars are scanned and how long it 88 // The code below will record again how many chars are scanned and how long it
118 // takes to scan them, even though we already did so in [scanReachableFiles]. 89 // takes to scan them, even though we already did so in [scanReachableFiles].
119 // Recording and reporting this twice is unnecessary, but we do so for now to 90 // Recording and reporting this twice is unnecessary, but we do so for now to
120 // validate that the results are consistent. 91 // validate that the results are consistent.
121 scanTimer = new Stopwatch(); 92 scanTimer = new Stopwatch();
122 var old = scanTotalChars; 93 var old = scanTotalChars;
123 scanTotalChars = 0; 94 scanTotalChars = 0;
95 var parseTimer = new Stopwatch()..start();
124 for (var source in files) { 96 for (var source in files) {
125 tokenize(source); 97 parseFull(source);
126 } 98 }
99 parseTimer.stop();
127 100
128 // Report size and scanning time again. See discussion above. 101 // Report size and scanning time again. See discussion above.
129 if (old != scanTotalChars) print('input size changed? ${old} chars'); 102 if (old != scanTotalChars) print('input size changed? ${old} chars');
130 report("scan", scanTimer.elapsedMicroseconds); 103 report("scan", scanTimer.elapsedMicroseconds);
104
105 var pTime = parseTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
106 report("parse", pTime);
131 } 107 }
132 108
133 /// Parses every file in [files] and reports the time spent doing so. 109 /// Parse the full body of [source] and return it's compilation unit.
134 void parseFiles(Set<Source> files) { 110 CompilationUnit parseFull(Source source) {
111 var token = tokenize(source);
112 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
113 return parser.parseCompilationUnit(token);
114 }
115
116 /// Report that metric [name] took [time] micro-seconds to process
117 /// [scanTotalChars] characters.
118 void report(String name, int time) {
119 var sb = new StringBuffer();
120 sb.write('$name: $time us, ${time ~/ 1000} ms');
121 sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
122 print('$sb');
123 }
124
125 /// Scans every file in [files] and reports the time spent doing so.
126 void scanFiles(Set<Source> files) {
135 // The code below will record again how many chars are scanned and how long it 127 // The code below will record again how many chars are scanned and how long it
136 // takes to scan them, even though we already did so in [scanReachableFiles]. 128 // takes to scan them, even though we already did so in [scanReachableFiles].
137 // Recording and reporting this twice is unnecessary, but we do so for now to 129 // Recording and reporting this twice is unnecessary, but we do so for now to
138 // validate that the results are consistent. 130 // validate that the results are consistent.
139 scanTimer = new Stopwatch(); 131 scanTimer = new Stopwatch();
140 var old = scanTotalChars; 132 var old = scanTotalChars;
141 scanTotalChars = 0; 133 scanTotalChars = 0;
142 var parseTimer = new Stopwatch()..start();
143 for (var source in files) { 134 for (var source in files) {
144 parseFull(source); 135 tokenize(source);
145 } 136 }
146 parseTimer.stop();
147 137
148 // Report size and scanning time again. See discussion above. 138 // Report size and scanning time again. See discussion above.
149 if (old != scanTotalChars) print('input size changed? ${old} chars'); 139 if (old != scanTotalChars) print('input size changed? ${old} chars');
150 report("scan", scanTimer.elapsedMicroseconds); 140 report("scan", scanTimer.elapsedMicroseconds);
151
152 var pTime = parseTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
153 report("parse", pTime);
154 } 141 }
155 142
156 /// Add to [files] all sources reachable from [start]. 143 /// Load and scans all files we need to process: files reachable from the
157 void collectSources(Source start, Set<Source> files) { 144 /// entrypoint and all core libraries automatically included by the VM.
158 if (!files.add(start)) return; 145 Set<Source> scanReachableFiles(Uri entryUri) {
159 var unit = parseDirectives(start); 146 var files = new Set<Source>();
160 for (var directive in unit.directives) { 147 var loadTimer = new Stopwatch()..start();
161 if (directive is UriBasedDirective) { 148 collectSources(sources.forUri2(entryUri), files);
162 var next = sources.resolveUri(start, directive.uri.stringValue); 149
163 collectSources(next, files); 150 var libs = [
164 } 151 "dart:async",
152 "dart:collection",
153 "dart:convert",
154 "dart:core",
155 "dart:developer",
156 "dart:_internal",
157 "dart:isolate",
158 "dart:math",
159 "dart:mirrors",
160 "dart:typed_data",
161 "dart:io"
162 ];
163
164 for (var lib in libs) {
165 collectSources(sources.forUri(lib), files);
165 } 166 }
167
168 loadTimer.stop();
169
170 print('input size: ${scanTotalChars} chars');
171 var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
172 report("load", loadTime);
173 report("scan", scanTimer.elapsedMicroseconds);
174 return files;
166 } 175 }
167 176
168 /// Uses the diet-parser to parse only directives in [source]. 177 /// Sets up analyzer to be able to load and resolve app, packages, and sdk
169 CompilationUnit parseDirectives(Source source) { 178 /// sources.
170 var token = tokenize(source); 179 Future setup(Uri entryUri) async {
171 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); 180 var provider = PhysicalResourceProvider.INSTANCE;
172 return parser.parseDirectives(token); 181 var packageMap = new ContextBuilder(provider, null, null)
173 } 182 .convertPackagesToMap(await findPackages(entryUri));
174 183 sources = new SourceFactory([
175 /// Parse the full body of [source] and return it's compilation unit. 184 new ResourceUriResolver(provider),
176 CompilationUnit parseFull(Source source) { 185 new PackageMapUriResolver(provider, packageMap),
177 var token = tokenize(source); 186 new DartUriResolver(
178 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); 187 new FolderBasedDartSdk(provider, provider.getFolder("sdk"))),
179 return parser.parseCompilationUnit(token); 188 ]);
180 } 189 }
181 190
182 /// Scan [source] and return the first token produced by the scanner. 191 /// Scan [source] and return the first token produced by the scanner.
183 Token tokenize(Source source) { 192 Token tokenize(Source source) {
184 scanTimer.start(); 193 scanTimer.start();
185 var contents = source.contents.data; 194 var contents = source.contents.data;
186 scanTotalChars += contents.length; 195 scanTotalChars += contents.length;
187 // TODO(sigmund): is there a way to scan from a random-access-file without 196 // TODO(sigmund): is there a way to scan from a random-access-file without
188 // first converting to String? 197 // first converting to String?
189 var scanner = new Scanner(source, new CharSequenceReader(contents), 198 var scanner = new Scanner(source, new CharSequenceReader(contents),
190 AnalysisErrorListener.NULL_LISTENER) 199 AnalysisErrorListener.NULL_LISTENER)
191 ..preserveComments = false; 200 ..preserveComments = false;
192 var token = scanner.tokenize(); 201 var token = scanner.tokenize();
193 scanTimer.stop(); 202 scanTimer.stop();
194 return token; 203 return token;
195 } 204 }
196
197 /// Report that metric [name] took [time] micro-seconds to process
198 /// [scanTotalChars] characters.
199 void report(String name, int time) {
200 var sb = new StringBuffer();
201 sb.write('$name: $time us, ${time ~/ 1000} ms');
202 sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
203 print('$sb');
204 }
OLDNEW
« no previous file with comments | « pkg/analyzer_cli/test/utils.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698