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; | 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/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:kernel/analyzer/loader.dart'; |
| 26 import 'package:kernel/kernel.dart'; |
25 import 'package:package_config/discovery.dart'; | 27 import 'package:package_config/discovery.dart'; |
26 | 28 |
27 /// Cumulative total number of chars scanned. | 29 /// Cumulative total number of chars scanned. |
28 int scanTotalChars = 0; | 30 int scanTotalChars = 0; |
29 | 31 |
30 /// Cumulative time spent scanning. | 32 /// Cumulative time spent scanning. |
31 Stopwatch scanTimer = new Stopwatch(); | 33 Stopwatch scanTimer = new Stopwatch(); |
32 | 34 |
33 /// Factory to load and resolve app, packages, and sdk sources. | 35 /// Factory to load and resolve app, packages, and sdk sources. |
34 SourceFactory sources; | 36 SourceFactory sources; |
35 | 37 |
36 main(List<String> args) async { | 38 main(List<String> args) async { |
37 // TODO(sigmund): provide sdk folder as well. | 39 // TODO(sigmund): provide sdk folder as well. |
38 if (args.length < 2) { | 40 if (args.length < 2) { |
39 print('usage: perf.dart <bench-id> <entry.dart>'); | 41 print('usage: perf.dart <bench-id> <entry.dart>'); |
40 exit(1); | 42 exit(1); |
41 } | 43 } |
42 var totalTimer = new Stopwatch()..start(); | 44 var totalTimer = new Stopwatch()..start(); |
43 | 45 |
44 var bench = args[0]; | 46 var bench = args[0]; |
45 var entryUri = Uri.base.resolve(args[1]); | 47 var entryUri = Uri.base.resolve(args[1]); |
46 | 48 |
47 await setup(entryUri); | 49 await setup(entryUri); |
48 | 50 |
49 if (bench == 'scan') { | 51 var handlers = { |
50 Set<Source> files = scanReachableFiles(entryUri); | 52 'scan': () async { |
51 // TODO(sigmund): consider replacing the warmup with instrumented snapshots. | 53 Set<SourceFile> files = scanReachableFiles(entryUri); |
52 for (int i = 0; i < 10; i++) scanFiles(files); | 54 // TODO(sigmund): replace the warmup with instrumented snapshots. |
53 } else if (bench == 'parse') { | 55 for (int i = 0; i < 10; i++) scanFiles(files); |
54 Set<Source> files = scanReachableFiles(entryUri); | 56 }, |
55 // TODO(sigmund): consider replacing the warmup with instrumented snapshots. | 57 'parse': () async { |
56 for (int i = 0; i < 10; i++) parseFiles(files); | 58 Set<SourceFile> files = scanReachableFiles(entryUri); |
57 } else { | 59 // TODO(sigmund): replace the warmup with instrumented snapshots. |
58 print('unsupported bench-id: $bench. Please specify "scan" or "parse"'); | 60 for (int i = 0; i < 10; i++) parseFiles(files); |
| 61 }, |
| 62 'kernel_gen_e2e': () async { |
| 63 // TODO(sigmund): remove. This is used to compute the input size, we |
| 64 // should extract input size from frontend instead. |
| 65 scanReachableFiles(entryUri); |
| 66 // TODO(sigmund): replace this warmup. Note that for very large programs, |
| 67 // the GC pressure on the VM seems to make this worse with time (maybe we |
| 68 // are leaking memory?). That's why we run it twice and not 10 times. |
| 69 for (int i = 0; i < 2; i++) await generateKernel(entryUri); |
| 70 }, |
| 71 }; |
| 72 |
| 73 var handler = handlers[bench]; |
| 74 if (handler == null) { |
59 // TODO(sigmund): implement the remaining benchmarks. | 75 // TODO(sigmund): implement the remaining benchmarks. |
| 76 print('unsupported bench-id: $bench. Please specify one of the following: ' |
| 77 '${handler.keys.join(", ")}'); |
60 exit(1); | 78 exit(1); |
61 } | 79 } |
| 80 await handler(); |
62 | 81 |
63 totalTimer.stop(); | 82 totalTimer.stop(); |
64 report("total", totalTimer.elapsedMicroseconds); | 83 report("total", totalTimer.elapsedMicroseconds); |
65 } | 84 } |
66 | 85 |
67 /// Sets up analyzer to be able to load and resolve app, packages, and sdk | 86 /// Sets up analyzer to be able to load and resolve app, packages, and sdk |
68 /// sources. | 87 /// sources. |
69 Future setup(Uri entryUri) async { | 88 Future setup(Uri entryUri) async { |
70 var provider = PhysicalResourceProvider.INSTANCE; | 89 var provider = PhysicalResourceProvider.INSTANCE; |
71 var packageMap = new ContextBuilder(provider, null, null) | 90 var packageMap = new ContextBuilder(provider, null, null) |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 } | 213 } |
195 | 214 |
196 /// Report that metric [name] took [time] micro-seconds to process | 215 /// Report that metric [name] took [time] micro-seconds to process |
197 /// [scanTotalChars] characters. | 216 /// [scanTotalChars] characters. |
198 void report(String name, int time) { | 217 void report(String name, int time) { |
199 var sb = new StringBuffer(); | 218 var sb = new StringBuffer(); |
200 sb.write('$name: $time us, ${time ~/ 1000} ms'); | 219 sb.write('$name: $time us, ${time ~/ 1000} ms'); |
201 sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms'); | 220 sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms'); |
202 print('$sb'); | 221 print('$sb'); |
203 } | 222 } |
| 223 |
| 224 // TODO(sigmund): replace this once kernel is produced by the frontend directly. |
| 225 Future<Program> generateKernel(Uri entryUri) async { |
| 226 var dartkTimer = new Stopwatch()..start(); |
| 227 var options = new DartOptions(strongMode: false, sdk: 'sdk'); |
| 228 var packages = |
| 229 await createPackages(options.packagePath, discoveryPath: entryUri.path); |
| 230 var repository = new Repository(); |
| 231 DartLoader loader = new DartLoader(repository, options, packages); |
| 232 |
| 233 Program program = loader.loadProgram(entryUri.path); |
| 234 List errors = loader.errors; |
| 235 if (errors.isNotEmpty) { |
| 236 const int errorLimit = 100; |
| 237 stderr.writeln(errors.take(errorLimit).join('\n')); |
| 238 if (errors.length > errorLimit) { |
| 239 stderr.writeln('[error] ${errors.length - errorLimit} errors not shown'); |
| 240 } |
| 241 } |
| 242 dartkTimer.stop(); |
| 243 report("kernel_gen_e2e", dartkTimer.elapsedMicroseconds); |
| 244 return program; |
| 245 } |
OLD | NEW |