Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 import 'package:front_end/src/scanner/reader.dart'; | 28 import 'package:front_end/src/scanner/reader.dart'; |
| 29 import 'package:front_end/src/scanner/scanner.dart'; | 29 import 'package:front_end/src/scanner/scanner.dart'; |
| 30 import 'package:front_end/src/scanner/token.dart'; | 30 import 'package:front_end/src/scanner/token.dart'; |
| 31 | 31 |
| 32 /// Cumulative total number of chars scanned. | 32 /// Cumulative total number of chars scanned. |
| 33 int scanTotalChars = 0; | 33 int scanTotalChars = 0; |
| 34 | 34 |
| 35 /// Cumulative time spent scanning. | 35 /// Cumulative time spent scanning. |
| 36 Stopwatch scanTimer = new Stopwatch(); | 36 Stopwatch scanTimer = new Stopwatch(); |
| 37 | 37 |
| 38 /// Cumulative time spent parsing. | |
| 39 Stopwatch parseTimer = new Stopwatch(); | |
| 40 | |
| 41 /// Cumulative time spent building unlinked summaries. | |
| 42 Stopwatch unlinkedSummarizeTimer = new Stopwatch(); | |
| 43 | |
| 38 /// Factory to load and resolve app, packages, and sdk sources. | 44 /// Factory to load and resolve app, packages, and sdk sources. |
| 39 SourceFactory sources; | 45 SourceFactory sources; |
| 40 | 46 |
| 41 main(List<String> args) async { | 47 main(List<String> args) async { |
| 42 // TODO(sigmund): provide sdk folder as well. | 48 // TODO(sigmund): provide sdk folder as well. |
| 43 if (args.length < 2) { | 49 if (args.length < 2) { |
| 44 print('usage: perf.dart <bench-id> <entry.dart>'); | 50 print('usage: perf.dart <bench-id> <entry.dart>'); |
| 45 exit(1); | 51 exit(1); |
| 46 } | 52 } |
| 47 var totalTimer = new Stopwatch()..start(); | 53 var totalTimer = new Stopwatch()..start(); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 | 165 |
| 160 /// Parses every file in [files] and reports the time spent doing so. | 166 /// Parses every file in [files] and reports the time spent doing so. |
| 161 void parseFiles(Set<Source> files) { | 167 void parseFiles(Set<Source> files) { |
| 162 // The code below will record again how many chars are scanned and how long it | 168 // The code below will record again how many chars are scanned and how long it |
| 163 // takes to scan them, even though we already did so in [scanReachableFiles]. | 169 // takes to scan them, even though we already did so in [scanReachableFiles]. |
| 164 // Recording and reporting this twice is unnecessary, but we do so for now to | 170 // Recording and reporting this twice is unnecessary, but we do so for now to |
| 165 // validate that the results are consistent. | 171 // validate that the results are consistent. |
| 166 scanTimer = new Stopwatch(); | 172 scanTimer = new Stopwatch(); |
| 167 var old = scanTotalChars; | 173 var old = scanTotalChars; |
| 168 scanTotalChars = 0; | 174 scanTotalChars = 0; |
| 169 var parseTimer = new Stopwatch()..start(); | 175 parseTimer = new Stopwatch(); |
| 170 for (var source in files) { | 176 for (var source in files) { |
| 171 parseFull(source); | 177 parseFull(source); |
| 172 } | 178 } |
| 173 parseTimer.stop(); | |
| 174 | 179 |
| 175 // Report size and scanning time again. See discussion above. | 180 // Report size and scanning time again. See discussion above. |
| 176 if (old != scanTotalChars) print('input size changed? ${old} chars'); | 181 if (old != scanTotalChars) print('input size changed? ${old} chars'); |
| 177 report("scan", scanTimer.elapsedMicroseconds); | 182 report("scan", scanTimer.elapsedMicroseconds); |
| 178 | 183 report("parse", parseTimer.elapsedMicroseconds); |
| 179 var pTime = parseTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds; | |
| 180 report("parse", pTime); | |
| 181 } | 184 } |
| 182 | 185 |
| 183 /// Produces unlinked summaries for every file in [files] and reports the time | 186 /// Produces unlinked summaries for every file in [files] and reports the time |
| 184 /// spent doing so. | 187 /// spent doing so. |
| 185 void unlinkedSummarizeFiles(Set<Source> files) { | 188 void unlinkedSummarizeFiles(Set<Source> files) { |
| 186 // The code below will record again how many chars are scanned and how long it | 189 // The code below will record again how many chars are scanned and how long it |
| 187 // takes to scan them, even though we already did so in [scanReachableFiles]. | 190 // takes to scan them, even though we already did so in [scanReachableFiles]. |
| 188 // Recording and reporting this twice is unnecessary, but we do so for now to | 191 // Recording and reporting this twice is unnecessary, but we do so for now to |
| 189 // validate that the results are consistent. | 192 // validate that the results are consistent. |
| 190 scanTimer = new Stopwatch(); | 193 scanTimer = new Stopwatch(); |
| 191 var old = scanTotalChars; | 194 var old = scanTotalChars; |
| 192 scanTotalChars = 0; | 195 scanTotalChars = 0; |
| 193 var summarizeTimer = new Stopwatch()..start(); | 196 parseTimer = new Stopwatch(); |
| 197 unlinkedSummarizeTimer = new Stopwatch(); | |
| 194 for (var source in files) { | 198 for (var source in files) { |
| 195 unlinkedSummarize(source); | 199 unlinkedSummarize(source); |
| 196 } | 200 } |
| 197 summarizeTimer.stop(); | |
| 198 | 201 |
| 199 if (old != scanTotalChars) print('input size changed? ${old} chars'); | 202 if (old != scanTotalChars) print('input size changed? ${old} chars'); |
| 200 | 203 report("scan", scanTimer.elapsedMicroseconds); |
| 201 // TODO(paulberry): subtract out scan/parse time? | 204 report("parse", parseTimer.elapsedMicroseconds); |
| 202 var summarizeTime = summarizeTimer.elapsedMicroseconds; | 205 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); |
|
Siggi Cherem (dart-lang)
2016/12/04 05:01:48
I wonder if we should continue to include the pars
Paul Berry
2016/12/05 16:01:01
Good idea. PTAL.
| |
| 203 report('unlinked summarize', summarizeTime); | |
| 204 } | 206 } |
| 205 | 207 |
| 206 /// Add to [files] all sources reachable from [start]. | 208 /// Add to [files] all sources reachable from [start]. |
| 207 void collectSources(Source start, Set<Source> files) { | 209 void collectSources(Source start, Set<Source> files) { |
| 208 if (!files.add(start)) return; | 210 if (!files.add(start)) return; |
| 209 var unit = parseDirectives(start); | 211 var unit = parseDirectives(start); |
| 210 for (var directive in unit.directives) { | 212 for (var directive in unit.directives) { |
| 211 if (directive is UriBasedDirective) { | 213 if (directive is UriBasedDirective) { |
| 212 var next = sources.resolveUri(start, directive.uri.stringValue); | 214 var next = sources.resolveUri(start, directive.uri.stringValue); |
| 213 collectSources(next, files); | 215 collectSources(next, files); |
| 214 } | 216 } |
| 215 } | 217 } |
| 216 } | 218 } |
| 217 | 219 |
| 218 /// Uses the diet-parser to parse only directives in [source]. | 220 /// Uses the diet-parser to parse only directives in [source]. |
| 219 CompilationUnit parseDirectives(Source source) { | 221 CompilationUnit parseDirectives(Source source) { |
| 220 var token = tokenize(source); | 222 var token = tokenize(source); |
| 221 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); | 223 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); |
| 222 return parser.parseDirectives(token); | 224 return parser.parseDirectives(token); |
| 223 } | 225 } |
| 224 | 226 |
| 225 /// Parse the full body of [source] and return it's compilation unit. | 227 /// Parse the full body of [source] and return it's compilation unit. |
| 226 CompilationUnit parseFull(Source source) { | 228 CompilationUnit parseFull(Source source) { |
| 227 var token = tokenize(source); | 229 var token = tokenize(source); |
| 230 parseTimer.start(); | |
| 228 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); | 231 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); |
| 229 return parser.parseCompilationUnit(token); | 232 var unit = parser.parseCompilationUnit(token); |
| 233 parseTimer.stop(); | |
| 234 return unit; | |
| 230 } | 235 } |
| 231 | 236 |
| 232 UnlinkedUnitBuilder unlinkedSummarize(Source source) { | 237 UnlinkedUnitBuilder unlinkedSummarize(Source source) { |
| 233 var unit = parseFull(source); | 238 var unit = parseFull(source); |
| 234 return serializeAstUnlinked(unit); | 239 unlinkedSummarizeTimer.start(); |
| 240 var unlinkedUnit = serializeAstUnlinked(unit); | |
| 241 unlinkedSummarizeTimer.stop(); | |
| 242 return unlinkedUnit; | |
| 235 } | 243 } |
| 236 | 244 |
| 237 /// Scan [source] and return the first token produced by the scanner. | 245 /// Scan [source] and return the first token produced by the scanner. |
| 238 Token tokenize(Source source) { | 246 Token tokenize(Source source) { |
| 239 scanTimer.start(); | 247 scanTimer.start(); |
| 240 var contents = source.contents.data; | 248 var contents = source.contents.data; |
| 241 scanTotalChars += contents.length; | 249 scanTotalChars += contents.length; |
| 242 // TODO(sigmund): is there a way to scan from a random-access-file without | 250 // TODO(sigmund): is there a way to scan from a random-access-file without |
| 243 // first converting to String? | 251 // first converting to String? |
| 244 var scanner = new _Scanner(contents); | 252 var scanner = new _Scanner(contents); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 282 const int errorLimit = 100; | 290 const int errorLimit = 100; |
| 283 stderr.writeln(errors.take(errorLimit).join('\n')); | 291 stderr.writeln(errors.take(errorLimit).join('\n')); |
| 284 if (errors.length > errorLimit) { | 292 if (errors.length > errorLimit) { |
| 285 stderr.writeln('[error] ${errors.length - errorLimit} errors not shown'); | 293 stderr.writeln('[error] ${errors.length - errorLimit} errors not shown'); |
| 286 } | 294 } |
| 287 } | 295 } |
| 288 dartkTimer.stop(); | 296 dartkTimer.stop(); |
| 289 report("kernel_gen_e2e", dartkTimer.elapsedMicroseconds); | 297 report("kernel_gen_e2e", dartkTimer.elapsedMicroseconds); |
| 290 return program; | 298 return program; |
| 291 } | 299 } |
| OLD | NEW |