Chromium Code Reviews| 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> |