Index: utils/tests/string_encoding/benchmark_runner.dart |
diff --git a/utils/tests/string_encoding/benchmark_runner.dart b/utils/tests/string_encoding/benchmark_runner.dart |
deleted file mode 100644 |
index 0f5495607a9c7c3a138425acf76597461134a625..0000000000000000000000000000000000000000 |
--- a/utils/tests/string_encoding/benchmark_runner.dart |
+++ /dev/null |
@@ -1,460 +0,0 @@ |
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-part of BenchmarkTests; |
- |
-/** |
- * The results of a single block of tests (count times run, overall time). |
- */ |
-class BlockSample { |
- BlockSample(this.count, this.durationNanos); |
- int count; |
- int durationNanos; |
- |
- static int _totalCount(List<BlockSample> samples) => |
- _sum(samples, int (BlockSample s) => s.count); |
- |
- static int _totalTime(List<BlockSample> samples) => |
- _sum(samples, int (BlockSample s) => s.durationNanos); |
- |
- static BlockSample _select(List<BlockSample> samples, |
- BlockSample selector(BlockSample a, BlockSample b)) { |
- BlockSample r = null; |
- for (BlockSample s in samples) { |
- r = (r == null) ? s : selector(r, s); |
- } |
- return r; |
- } |
- |
- static int _sum(List<BlockSample> samples, int extract(BlockSample s)) { |
- int total = 0; |
- for (BlockSample s in samples) { |
- total += extract(s); |
- } |
- return total; |
- } |
-} |
- |
-/** |
- * Uses sample data to build a performance model for a test. Construct |
- * the model from a set of sample results, and it generates a simple |
- * predivtive model for execution of future requests. It uses |
- * a simple least-squares linear solution to build the model. |
- */ |
-class PerformanceModel { |
- PerformanceModel.calculate(List<BlockSample> source) { |
- if (0 == source.length) { |
- throw "Missing data exception"; |
- } else if (1 == source.length) { |
- overheadNanos = 0; |
- perRequestNanos = source[0].durationNanos / source[0].count; |
- } else { |
- double n = source.length.toDouble(); |
- double sumY = BlockSample._totalTime(source).toDouble(); |
- double sumXSquared = BlockSample._sum(source, |
- int _(BlockSample s) => s.count * s.count).toDouble(); |
- double sumX = BlockSample._totalCount(source).toDouble(); |
- double sumXY = BlockSample._sum(source, |
- int _(BlockSample s) => s.durationNanos * s.count).toDouble(); |
- |
- overheadNanos = |
- ((((sumY * sumXSquared) - (sumX * sumXY)) / |
- ((n * sumXSquared) - (sumX * sumX))) / source.length).toInt(); |
- |
- perRequestNanos = |
- (((n * sumXY) - (sumX * sumY)) / |
- ((n * sumXSquared) - (sumX * sumX))).toInt(); |
- } |
- } |
- |
- bool isValid() => overheadNanos >= 0 && perRequestNanos >= 0; |
- |
- int overheadNanos; |
- int perRequestNanos; |
- int repsFor(int targetDurationNanos, [int blocksize = -1]) { |
- if (blocksize <= 0) { |
- return ((targetDurationNanos - overheadNanos) / perRequestNanos).toInt(); |
- } else { |
- int blockTime = overheadNanos + (blocksize * perRequestNanos); |
- int fullBlocks = targetDurationNanos ~/ blockTime; |
- int extraReps = |
- ((targetDurationNanos - (fullBlocks * blockTime)) - overheadNanos) |
- ~/ perRequestNanos; |
- return ((fullBlocks * blocksize) + extraReps).toInt(); |
- } |
- } |
-} |
- |
-/** |
- * Report overall test performance |
- */ |
-class TestReport { |
- TestReport(this.id, this.desc, this.warmup, this.results) { |
- spaceChar = " ".codeUnits[0]; |
- } |
- |
- int spaceChar; |
- |
- int resultsCount() => BlockSample._totalCount(results); |
- |
- int resultsNanos() => BlockSample._totalTime(results); |
- |
- int resultsBestNanos() { |
- BlockSample best = bestBlock(results); |
- return best.durationNanos ~/ best.count; |
- } |
- |
- int resultsMeanNanos() => |
- BlockSample._totalTime(results) ~/ BlockSample._totalCount(results); |
- |
- int resultsWorstNanos() { |
- BlockSample worst = worstBlock(results); |
- return worst.durationNanos / worst.count; |
- } |
- |
- int warmupBestNanos() { |
- BlockSample best = bestBlock(warmup); |
- return best.durationNanos / best.count; |
- } |
- |
- int warmupMeanNanos() => _totalTime(warmup) / _totalCount(warmup); |
- |
- int warmupWorstNanos() { |
- BlockSample worst = worstBlock(warmup); |
- return worst.durationNanos / worst.count; |
- } |
- |
- BlockSample bestBlock(List<BlockSample> samples) { |
- return BlockSample._select(samples, |
- BlockSample selector(BlockSample a, BlockSample b) { |
- return a.durationNanos <= b.durationNanos ? a : b; |
- }); |
- } |
- |
- BlockSample worstBlock(List<BlockSample> samples) { |
- return BlockSample._select(samples, |
- BlockSample selector(BlockSample a, BlockSample b) { |
- return a.durationNanos >= b.durationNanos ? a : b; |
- }); |
- } |
- |
- void printReport() { |
- String text = _leftAlign("${id}", 30); |
- String totalCount = _rightAlign(resultsCount().toString(), 10); |
- String totalDurationMs = |
- _rightAlign(_stringifyDoubleAsInt(resultsNanos() / 1E6), 6); |
- String meanDuration = |
- _rightAlign(_stringifyDoubleAsInt(resultsMeanNanos().toDouble()), 8); |
- |
- print("${text} total time:${totalDurationMs} ms" + |
- " iterations:${totalCount} mean:${meanDuration} ns"); |
- } |
- |
- void printReportWithThroughput(int sizeBytes) { |
- String text = _leftAlign("${id}", 30); |
- String totalCount = _rightAlign(resultsCount().toString(), 10); |
- String totalDurationMs = |
- _rightAlign(_stringifyDoubleAsInt(resultsNanos() / 1E6), 6); |
- String meanDuration = |
- _rightAlign(_stringifyDoubleAsInt(resultsMeanNanos()), 8); |
- |
- int totalBytes = sizeBytes * resultsCount(); |
- String mbPerSec = (((1E9 * sizeBytes * resultsCount()) / |
- (1024 * 1024 * resultsNanos()))).toString(); |
- print("${text} total time:${totalDurationMs} ms" + |
- " iterations:${totalCount}" + |
- " mean:${meanDuration} ns; ${mbPerSec} MB/sec"); |
- } |
- |
- String _leftAlign(String s, int width) { |
- List<int> outCodes = new List<int>.filled(width, spaceChar); |
- outCodes.setRange(0, Math.min(width, s.length), s.codeUnits); |
- return new String.fromCharCodes(outCodes); |
- } |
- |
- String _rightAlign(String s, int width) { |
- List<int> outCodes = new List<int>.filled(width, spaceChar); |
- int fromIndex = Math.max(0, width - s.length); |
- int length = Math.min(width, s.length); |
- outCodes.setRange(fromIndex, fromIndex + length, s.codeUnits); |
- return new String.fromCharCodes(outCodes); |
- } |
- |
- static String _stringifyDoubleAsInt(double val) { |
- if (val.isInfinite || val.isNaN) { |
- return "NaN"; |
- } else { |
- return val.toInt().toString(); |
- } |
- } |
- |
- String id; |
- String desc; |
- List<BlockSample> warmup; |
- List<BlockSample> results; |
-} |
- |
-class Runner { |
- static List<String> arguments; // Set by main. |
- |
- static bool runTest(String testId) { |
- return arguments.length == 0 || |
- arguments.any((String id) => id == testId); |
- } |
-} |
- |
-/** |
- * Run traditional blocking-style tests. Tests may be run a specified number |
- * of times, or they can be run based on performance to estimate a particular |
- * duration. |
- */ |
-class BenchmarkRunner extends Runner { |
- static void runCount(String id, String desc, CountTestConfig config, |
- Function test) { |
- if (runTest(id)) { |
- List<BlockSample> warmupSamples = _runTests(test, config._warmup, 1); |
- List<BlockSample> resultSamples = _runTests(test, config._reps, 1); |
- config.reportHandler( |
- new TestReport(id, desc, warmupSamples, resultSamples)); |
- } |
- } |
- |
- static void runTimed(String id, String desc, TimedTestConfig config, |
- Function test) { |
- if (runTest(id)) { |
- List<BlockSample> warmupSamples = _runTests(test, config._warmup, 1); |
- PerformanceModel model = _calibrate(config._minSampleTimeMs, 16, test); |
- int reps = model.repsFor(1E6 * config._targetTimeMs, config._blocksize); |
- int blocksize = config._blocksize < 0 ? reps : config._blocksize; |
- List<BlockSample> resultSamples = _runTests(test, reps, blocksize); |
- config.reportHandler( |
- new TestReport(id, desc, warmupSamples, resultSamples)); |
- } |
- } |
- |
- static PerformanceModel _calibrate(int minSampleTimeMs, int maxAttempts, |
- Function test) { |
- PerformanceModel model; |
- int i = 0; |
- do { |
- model = _buildPerformanceModel(minSampleTimeMs, test); |
- i++; |
- } while (i < maxAttempts && !model.isValid()); |
- return model; |
- } |
- |
- static PerformanceModel _buildPerformanceModel( |
- int minSampleTimeMs, Function test) { |
- int iterations = 1; |
- List<BlockSample> calibrationResults = []; |
- BlockSample calibration = _execBlock(test, iterations); |
- calibrationResults.add(calibration); |
- while (calibration.durationNanos < (1E6 * minSampleTimeMs)) { |
- iterations *= 2; |
- calibration = _execBlock(test, iterations); |
- calibrationResults.add(calibration); |
- } |
- return new PerformanceModel.calculate(calibrationResults); |
- } |
- |
- static List<BlockSample> _runTests(Function test, int count, int blocksize) { |
- List<BlockSample> samples = []; |
- for (int rem = count; rem > 0; rem -= blocksize) { |
- BlockSample bs = _execBlock(test, Math.min(blocksize, rem)); |
- samples.add(bs); |
- } |
- return samples; |
- } |
- |
- static BlockSample _execBlock(Function test, int count) { |
- Stopwatch s = new Stopwatch(); |
- s.start(); |
- for (int i = 0; i < count; i++) { |
- test(); |
- } |
- s.stop(); |
- return new BlockSample(count, s.elapsedMicroseconds * 1000); |
- } |
-} |
- |
-/** |
- * Define CPSTest type. |
- */ |
-typedef void CPSTest(Function continuation); |
- |
-typedef void ReportHandler(TestReport r); |
- |
-/** |
- * Run non-blocking-style using Continuation Passing Style callbacks. Tests may |
- * be run a specified number of times, or they can be run based on performance |
- * to estimate a particular duration. |
- */ |
-class CPSBenchmarkRunner extends Runner { |
- |
- CPSBenchmarkRunner(): _cpsTests = []; |
- |
- void addTest(CPSTest test) { |
- _cpsTests.add(test); |
- } |
- |
- void runTests([int index = 0, Function continuation = null]) { |
- if (index < _cpsTests.length) { |
- _cpsTests[index](_(){ |
- _addToEventQueue(_() => runTests(index + 1, continuation)); |
- }); |
- } else { |
- if (null != continuation) { |
- _addToEventQueue(_() => continuation()); |
- } |
- } |
- } |
- |
- List<CPSTest> _cpsTests; |
- |
- static void runCount(String id, String desc, CountTestConfig config, |
- CPSTest test, void continuation()) { |
- if (runTest(id)) { |
- _runTests(test, config._warmup, 1, (List<BlockSample> warmupSamples){ |
- int blocksize = |
- config._blocksize <= 0 ? config._reps : config._blocksize; |
- _runTests(test, config._reps, blocksize, |
- _(List<BlockSample> resultSamples) { |
- config.reportHandler( |
- new TestReport(id, desc, warmupSamples, resultSamples)); |
- continuation(); |
- }); |
- }); |
- } else { |
- continuation(); |
- } |
- } |
- |
- static void runTimed(String id, String desc, TimedTestConfig config, |
- CPSTest test, void continuation()) { |
- if (runTest(id)) { |
- _runTests(test, config._warmup, 1, (List<BlockSample> warmupSamples){ |
- _calibrate(config._minSampleTimeMs, 5, test, (PerformanceModel model){ |
- int reps = |
- model.repsFor(1E6 * config._targetTimeMs, config._blocksize); |
- int blocksize = |
- config._blocksize <= 0 ? reps : config._blocksize; |
- _runTests(test, reps, blocksize, (List<BlockSample> results) { |
- config.reportHandler( |
- new TestReport(id, desc, warmupSamples, results)); |
- continuation(); |
- }); |
- }); |
- }); |
- } else { |
- continuation(); |
- } |
- } |
- |
- static void nextTest(Function testLoop, int iteration) { |
- _addToEventQueue(() => testLoop(iteration + 1)); |
- } |
- |
- static void _calibrate(int minSampleTimeMs, int maxAttempts, |
- CPSTest test, void continuation(PerformanceModel model)) { |
- _buildPerformanceModel(minSampleTimeMs, test, (PerformanceModel model){ |
- if (maxAttempts > 1 && !model.isValid()) { |
- _calibrate(minSampleTimeMs, maxAttempts - 1, test, continuation); |
- } else { |
- continuation(model); |
- } |
- }); |
- } |
- |
- static void _buildPerformanceModel( |
- int minSampleTimeMs, CPSTest test, void continuation(PerformanceModel m), |
- [int iterations = 1, List<BlockSample> calibrationResults = null]) { |
- List<BlockSample> _calibrationResults = |
- null == calibrationResults ? [] : calibrationResults; |
- _runTests(test, iterations, 1000, (List<BlockSample> calibration) { |
- _calibrationResults.addAll(calibration); |
- if (BlockSample._totalTime(calibration) < (1E6 * minSampleTimeMs)) { |
- _buildPerformanceModel(minSampleTimeMs, test, continuation, |
- iterations: iterations * 2, |
- calibrationResults: _calibrationResults); |
- } else { |
- PerformanceModel model = |
- new PerformanceModel.calculate(_calibrationResults); |
- continuation(model); |
- } |
- }); |
- } |
- |
- static void _runTests(CPSTest test, int reps, int blocksize, |
- void continuation(List<BlockSample> samples), |
- [List<BlockSample> samples = null]) { |
- List<BlockSample> localSamples = (null == samples) ? [] : samples; |
- if (reps > 0) { |
- int blockCount = Math.min(blocksize, reps); |
- _execBlock(test, blockCount, (BlockSample sample){ |
- localSamples.add(sample); |
- _addToEventQueue(() => |
- _runTests(test, reps - blockCount, blocksize, |
- continuation, localSamples)); |
- }); |
- } else { |
- continuation(localSamples); |
- } |
- } |
- |
- static void _execBlock(CPSTest test, int count, |
- void continuation(BlockSample sample)) { |
- Stopwatch s = new Stopwatch(); |
- s.start(); |
- _innerLoop(test, count, () { |
- s.stop(); |
- continuation(new BlockSample(count, s.elapsedInUs() * 1000)); |
- }); |
- } |
- |
- static void _innerLoop(CPSTest test, int remainingCount, |
- Function continuation) { |
- if (remainingCount > 1) { |
- test(() => _innerLoop(test, remainingCount - 1, continuation)); |
- } else { |
- continuation(); |
- } |
- } |
- |
- static void _addToEventQueue(Function action) { |
- Timer.run(action); |
- } |
-} |
- |
-class CountTestConfig { |
- CountTestConfig(int this._warmup, int this._reps, |
- [int blocksize = -1, ReportHandler reportHandler = null]) { |
- this._blocksize = blocksize; |
- this._reportHandler = (null == reportHandler) ? |
- _(TestReport r) => r.printReport() : reportHandler; |
- } |
- |
- Function _reportHandler; |
- Function get reportHandler => _reportHandler; |
- int _warmup; |
- int _reps; |
- int _blocksize; |
-} |
- |
-class TimedTestConfig { |
- TimedTestConfig(int this._warmup, int this._targetTimeMs, |
- [int minSampleTimeMs = 100, int blocksize = -1, |
- ReportHandler reportHandler = null]) : |
- this._minSampleTimeMs = minSampleTimeMs, |
- this._blocksize = blocksize { |
- this._reportHandler = (null == reportHandler) ? |
- _(TestReport r) => r.printReport() : reportHandler; |
- } |
- |
- Function _reportHandler; |
- Function get reportHandler => _reportHandler; |
- int _warmup; |
- int _targetTimeMs; |
- int _minSampleTimeMs; |
- int _blocksize; |
-} |