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