Index: tracing/tracing/metrics/v8/utils_test.html |
diff --git a/tracing/tracing/metrics/v8/utils_test.html b/tracing/tracing/metrics/v8/utils_test.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..55cd8e5e2a42efd8d6246faee9279d669b5af3d5 |
--- /dev/null |
+++ b/tracing/tracing/metrics/v8/utils_test.html |
@@ -0,0 +1,154 @@ |
+<!DOCTYPE html> |
+<!-- |
+Copyright 2016 The Chromium Authors. All rights reserved. |
+Use of this source code is governed by a BSD-style license that can be |
+found in the LICENSE file. |
+--> |
+ |
+<link rel="import" href="/tracing/metrics/v8/utils.html"> |
+ |
+<script> |
+'use strict'; |
+ |
+tr.b.unittest.testSuite(function() { |
+ |
+ var unionOfIntervals = tr.metrics.v8.utils.unionOfIntervals; |
+ |
+ function interval(start, end) { |
+ return {start: start, end: end}; |
+ } |
+ |
+ /** |
+ * Brute force computation of the mutator utilization. |
+ * The function steps from the start to the end and for each step |
+ * computes the mutator utilization. |
+ */ |
+ function mutatorUtilizationSlow(start, end, timeWindow, intervals) { |
+ var STEP = 0.001; |
+ function timeToIndex(time) { |
+ return Math.floor((time - start) / STEP); |
+ }; |
+ var N = timeToIndex(end) + 1; |
+ // bitmap[i] === true means that GC is active at time i. |
+ var bitmap = new Array(N); |
+ for (var i = 0; i < N; i++) |
+ bitmap[i] = false; |
+ intervals.forEach(function(interval) { |
+ var start = timeToIndex(interval.start); |
+ var end = timeToIndex(interval.end); |
+ for (var i = start; i < end; i++) |
+ bitmap[i] = true; |
+ }); |
+ var pause = new Array(N); |
+ for (var i = 0; i < N; i++) |
+ pause[i] = (i > 0 ? pause[i - 1] : 0) + (bitmap[i] ? 1 : 0); |
+ var windowWidth = timeToIndex(timeWindow); |
+ var mu = new Array(Math.max(N - windowWidth, 0)); |
+ for (var i = 0; i < mu.length; i++) { |
+ var value = pause[i + windowWidth] - pause[i]; |
+ mu[i] = 1.0 - value / windowWidth; |
+ } |
+ mu.sort((a, b) => a - b); |
+ var max_ = mu.reduce((acc, x) => Math.max(acc, x), 0); |
+ var min_ = mu.reduce((acc, x) => Math.min(acc, x), 0); |
+ var average_ = mu.reduce((acc, x) => (acc + x), 0) / mu.length; |
+ return { |
+ get average() { |
petrcermak
2016/04/25 12:31:17
You're making your code less efficient by wrapping
ulan
2016/04/25 12:46:26
Yeah, this code was strange. Changed it as you sug
|
+ return average_; |
+ }, |
+ get min() { |
+ return min_; |
+ }, |
+ get max() { |
+ return max_; |
+ }, |
+ percentile: function(percent) { |
+ return mu[Math.floor(percent * (mu.length - 1))]; |
+ } |
+ }; |
+ } |
+ |
+ /** |
+ * Constructs PiecewiseLinearFunction from pieces. |
+ * @param {!Array<!{x1: number, y1: number, x2: number, y2: number}>} pieces |
+ * The list of pieces ordered by the x coordinate. |
+ */ |
+ function createExpectedFunction(pieces) { |
+ var f = new tr.b.PiecewiseLinearFunction(); |
+ pieces.forEach(function(p) { |
+ f.push(p.x1, p.y1, p.x2, p.y2); |
+ }); |
+ return f; |
+ } |
+ |
+ test('unionOfIntervals', function() { |
+ var list, union; |
+ assert.deepEqual(unionOfIntervals([]), []); |
+ assert.deepEqual(unionOfIntervals([interval(1, 1)]), [interval(1, 1)]); |
+ assert.deepEqual( |
+ unionOfIntervals([interval(0, 1), interval(1, 2), interval(2, 3)]), |
+ [interval(0, 3)]); |
+ assert.deepEqual( |
+ unionOfIntervals([interval(0, 1), interval(1, 2), interval(3, 3)]), |
+ [interval(0, 2), interval(3, 3)]); |
+ assert.deepEqual( |
+ unionOfIntervals([interval(0, 10), interval(1, 2), interval(3, 3)]), |
+ [interval(0, 10)]); |
+ assert.deepEqual( |
+ unionOfIntervals([interval(0, 10), interval(1, 2), interval(3, 11)]), |
+ [interval(0, 11)]); |
+ assert.deepEqual( |
+ unionOfIntervals([interval(3, 10), interval(1, 2), interval(11, 11)]), |
+ [interval(1, 2), interval(3, 10), interval(11, 11)]); |
+ }); |
+ |
+ test('basicMutatorUtilization', function() { |
+ assert.deepEqual( |
+ tr.metrics.v8.utils.mutatorUtilization(0, 40, 10, [interval(10, 20)]), |
+ createExpectedFunction([ |
+ { x1: 0, y1: 1.0, x2: 10, y2: 0.0 }, |
+ { x1: 10, y1: 0.0, x2: 20, y2: 1.0 }, |
+ { x1: 20, y1: 1.0, x2: 30, y2: 1.0 }]) |
+ ); |
+ assert.deepEqual( |
+ tr.metrics.v8.utils.mutatorUtilization(0, 40, 10, [interval(10, 15)]), |
+ createExpectedFunction([ |
+ { x1: 0, y1: 1.0, x2: 5, y2: 0.5 }, |
+ { x1: 5, y1: 0.5, x2: 10, y2: 0.5 }, |
+ { x1: 10, y1: 0.5, x2: 15, y2: 1.0 }, |
+ { x1: 15, y1: 1.0, x2: 30, y2: 1.0 }]) |
+ ); |
+ assert.deepEqual( |
+ tr.metrics.v8.utils.mutatorUtilization(0, 60, 20, |
+ [interval(30, 35), interval(40, 45)]), |
+ createExpectedFunction([ |
+ { x1: 0, y1: 1.0, x2: 10, y2: 1.0 }, |
+ { x1: 10, y1: 1.0, x2: 15, y2: 0.75 }, |
+ { x1: 15, y1: 0.75, x2: 20, y2: 0.75 }, |
+ { x1: 20, y1: 0.75, x2: 25, y2: 0.5 }, |
+ { x1: 25, y1: 0.5, x2: 30, y2: 0.5 }, |
+ { x1: 30, y1: 0.5, x2: 35, y2: 0.75 }, |
+ { x1: 35, y1: 0.75, x2: 40, y2: 0.75 }]) |
+ ); |
+ }); |
+ |
+ test('mutatorUtilization', function() { |
+ var pauses, actual, expected; |
+ pauses = [interval(10, 20), |
+ interval(15, 23), |
+ interval(30, 31), |
+ interval(33, 34), |
+ interval(60, 61), |
+ interval(61, 63), |
+ interval(80, 88)]; |
+ actual = tr.metrics.v8.utils.mutatorUtilization(0, 100, 7, pauses); |
+ expected = mutatorUtilizationSlow(0, 100, 7, pauses); |
+ assert.closeTo(expected.average, actual.average, 1e-3); |
+ assert.closeTo(expected.max, actual.max, 1e-3); |
+ assert.closeTo(expected.min, actual.min, 1e-3); |
+ assert.closeTo(expected.percentile(0.5), actual.percentile(0.5), 1e-3); |
+ assert.closeTo(expected.percentile(0.9), actual.percentile(0.9), 1e-3); |
+ }); |
+ |
+}); |
+</script> |