| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2017, 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 import 'dart:async'; | |
| 6 import 'dart:convert'; | |
| 7 import 'dart:math'; | |
| 8 import 'dart:io'; | |
| 9 | |
| 10 import 'standard_deviation.dart'; | |
| 11 | |
| 12 const String bRootPath = const String.fromEnvironment("bRoot"); | |
| 13 const int abIterations = | |
| 14 const int.fromEnvironment("abIterations", defaultValue: 15); | |
| 15 const int iterations = | |
| 16 const int.fromEnvironment("iterations", defaultValue: 15); | |
| 17 | |
| 18 /// Compare the performance of two different fast implementations | |
| 19 /// by alternately launching the compile application in this directory | |
| 20 /// and the compile application location in the repo specified by "bRoot" | |
| 21 /// via -DbRoot=/absolute/path/to/other/sdk/repo | |
| 22 main(List<String> args) async { | |
| 23 print(args); | |
| 24 if (bRootPath == null) { | |
| 25 print('Expected -DbRoot=/absolute/path/to/other/sdk/repo'); | |
| 26 exit(1); | |
| 27 } | |
| 28 | |
| 29 // The root of this Dart SDK repo "A" | |
| 30 Uri aRoot = Platform.script.resolve('../../../..'); | |
| 31 | |
| 32 // The root of the other Dart SDK repo "B" | |
| 33 Uri bRoot = new Uri.directory(bRootPath); | |
| 34 | |
| 35 // Sanity check | |
| 36 String relPath = 'pkg/front_end/tool/fasta/compile.dart'; | |
| 37 Uri aCompile = aRoot.resolve(relPath); | |
| 38 if (!new File(aCompile.toFilePath()).existsSync()) { | |
| 39 print('Failed to find $aCompile'); | |
| 40 exit(1); | |
| 41 } | |
| 42 Uri bCompile = bRoot.resolve(relPath); | |
| 43 if (!new File(bCompile.toFilePath()).existsSync()) { | |
| 44 print('Failed to find $bCompile'); | |
| 45 exit(1); | |
| 46 } | |
| 47 | |
| 48 print('Comparing:'); | |
| 49 print('A: $aCompile'); | |
| 50 print('B: $bCompile'); | |
| 51 print(''); | |
| 52 | |
| 53 List<double> aCold = <double>[]; | |
| 54 List<double> aWarm = <double>[]; | |
| 55 List<double> bCold = <double>[]; | |
| 56 List<double> bWarm = <double>[]; | |
| 57 | |
| 58 var stopwatch = new Stopwatch()..start(); | |
| 59 for (int count = 0; count < abIterations; ++count) { | |
| 60 print('A/B iteration ${count + 1} of $abIterations ...'); | |
| 61 await run(aRoot, aCompile, args, aCold, aWarm); | |
| 62 await run(bRoot, bCompile, args, bCold, bWarm); | |
| 63 } | |
| 64 stopwatch.stop(); | |
| 65 print('Overall run time: ${stopwatch.elapsed.inMinutes} minutes'); | |
| 66 | |
| 67 print(''); | |
| 68 print('Raw data:'); | |
| 69 print('A cold, A warm, B cold, B warm'); | |
| 70 for (int index = 0; index < aCold.length; ++index) { | |
| 71 print('${aCold[index]}, ${aWarm[index]}, ${bCold[index]}, ${bWarm[index]}'); | |
| 72 } | |
| 73 | |
| 74 if (aWarm.length < 1) { | |
| 75 return; | |
| 76 } | |
| 77 | |
| 78 double aColdMean = average(aCold); | |
| 79 double aWarmMean = average(aWarm); | |
| 80 double bColdMean = average(bCold); | |
| 81 double bWarmMean = average(bWarm); | |
| 82 | |
| 83 print(''); | |
| 84 print('Average:'); | |
| 85 print('$aColdMean, $aWarmMean, $bColdMean, $bWarmMean'); | |
| 86 | |
| 87 if (aWarm.length < 2) { | |
| 88 return; | |
| 89 } | |
| 90 | |
| 91 double aColdStdDev = standardDeviation(aColdMean, aCold); | |
| 92 double aWarmStdDev = standardDeviation(aWarmMean, aWarm); | |
| 93 double bColdStdDev = standardDeviation(bColdMean, bCold); | |
| 94 double bWarmStdDev = standardDeviation(bWarmMean, bWarm); | |
| 95 | |
| 96 double aColdSDM = standardDeviationOfTheMean(aCold, aColdStdDev); | |
| 97 double aWarmSDM = standardDeviationOfTheMean(aWarm, aWarmStdDev); | |
| 98 double bColdSDM = standardDeviationOfTheMean(bCold, bColdStdDev); | |
| 99 double bWarmSDM = standardDeviationOfTheMean(bWarm, bWarmStdDev); | |
| 100 | |
| 101 print(''); | |
| 102 print('Uncertainty:'); | |
| 103 print('$aColdSDM, $aWarmSDM, $bColdSDM, $bWarmSDM'); | |
| 104 | |
| 105 double coldDelta = aColdMean - bColdMean; | |
| 106 double coldUncertainty = sqrt(pow(aColdSDM, 2) + pow(bColdSDM, 2)); | |
| 107 double warmDelta = aWarmMean - bWarmMean; | |
| 108 double warmUncertainty = sqrt(pow(aWarmSDM, 2) + pow(bWarmSDM, 2)); | |
| 109 | |
| 110 double coldDeltaPercent = (coldDelta / bColdMean * 1000).round() / 10; | |
| 111 double coldUncertaintyPercent = | |
| 112 (coldUncertainty / bColdMean * 1000).round() / 10; | |
| 113 double warmDeltaPercent = (warmDelta / bWarmMean * 1000).round() / 10; | |
| 114 double warmUncertaintyPercent = | |
| 115 (warmUncertainty / bWarmMean * 1000).round() / 10; | |
| 116 | |
| 117 double coldBest = coldDelta - 3 * coldUncertainty; | |
| 118 double coldBestPercent = coldDeltaPercent - 3 * coldUncertaintyPercent; | |
| 119 double coldWorst = coldDelta + 3 * coldUncertainty; | |
| 120 double coldWorstPercent = coldDeltaPercent + 3 * coldUncertaintyPercent; | |
| 121 | |
| 122 double warmBest = warmDelta - 3 * warmUncertainty; | |
| 123 double warmBestPercent = warmDeltaPercent - 3 * warmUncertaintyPercent; | |
| 124 double warmWorst = warmDelta + 3 * warmUncertainty; | |
| 125 double warmWorstPercent = warmDeltaPercent + 3 * warmUncertaintyPercent; | |
| 126 | |
| 127 print(''); | |
| 128 print('Summary:'); | |
| 129 print('$coldDelta, $coldDeltaPercent%, A cold start - B cold start'); | |
| 130 print('$coldUncertainty, $coldUncertaintyPercent%, Propagated uncertainty'); | |
| 131 print('$coldBest, $coldBestPercent%, 99.9% best case'); | |
| 132 print('$coldWorst, $coldWorstPercent%, 99.9% worst case'); | |
| 133 print(''); | |
| 134 print('$warmDelta, $warmDeltaPercent%, A warm runs - B warm runs'); | |
| 135 print('$warmUncertainty, $warmUncertaintyPercent%, Propagated uncertainty'); | |
| 136 print('$warmBest, $warmBestPercent%, 99.9% best case'); | |
| 137 print('$warmWorst, $warmWorstPercent%, 99.9% worst case'); | |
| 138 } | |
| 139 | |
| 140 const String _iterationTag = '=== Iteration '; | |
| 141 const String _summaryTag = 'Summary: {"'; | |
| 142 | |
| 143 /// Launch the specified dart program, forwarding all arguments and environment | |
| 144 /// that was passed to this program | |
| 145 Future<Null> run(Uri workingDir, Uri dartApp, List<String> args, | |
| 146 List<double> cold, List<double> warm) async { | |
| 147 print('Running $dartApp'); | |
| 148 | |
| 149 void processLine(String line) { | |
| 150 if (line.startsWith(_iterationTag)) { | |
| 151 // Show progress | |
| 152 stdout | |
| 153 ..write('.') | |
| 154 ..flush(); | |
| 155 return; | |
| 156 } | |
| 157 if (line.startsWith(_summaryTag)) { | |
| 158 String json = line.substring(_summaryTag.length - 2); | |
| 159 Map<String, dynamic> results = JSON.decode(json); | |
| 160 List<double> elapsedTimes = results['elapsedTimes']; | |
| 161 print('\nElapse times: $elapsedTimes'); | |
| 162 if (elapsedTimes.length > 0) { | |
| 163 cold.add(elapsedTimes[0]); | |
| 164 } | |
| 165 if (elapsedTimes.length > 4) { | |
| 166 // Drop the first 3 and average the remaining | |
| 167 warm.add(average(elapsedTimes.sublist(3))); | |
| 168 } | |
| 169 return; | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 String workingDirPath = workingDir.toFilePath(); | |
| 174 List<String> procArgs = <String>[ | |
| 175 '-Diterations=$iterations', | |
| 176 '-Dsummary=true', | |
| 177 dartApp.toFilePath() | |
| 178 ]; | |
| 179 procArgs.addAll(args); | |
| 180 | |
| 181 Process process = await Process.start(Platform.executable, procArgs, | |
| 182 workingDirectory: workingDirPath); | |
| 183 stderr.addStream(process.stderr); | |
| 184 StreamSubscription<String> stdOutSubscription; | |
| 185 stdOutSubscription = process.stdout | |
| 186 .transform(UTF8.decoder) | |
| 187 .transform(new LineSplitter()) | |
| 188 .listen(processLine, onDone: () { | |
| 189 stdOutSubscription.cancel(); | |
| 190 }, onError: (e) { | |
| 191 print('Error: $e'); | |
| 192 stdOutSubscription.cancel(); | |
| 193 }); | |
| 194 int code = await process.exitCode; | |
| 195 if (code != 0) { | |
| 196 throw 'fail: $code'; | |
| 197 } | |
| 198 print(''); | |
| 199 } | |
| OLD | NEW |