From 873233e825dc44690cea1959f3898268ef4d1c5e Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Tue, 30 Aug 2016 09:55:14 -0700 Subject: [PATCH] feat(benchpress): also report the statistics in the generated file --- .../src/reporter/console_reporter.ts | 29 ++++------------ .../src/reporter/json_file_reporter.ts | 8 ++++- .../@angular/benchpress/src/reporter/util.ts | 33 +++++++++++++++++++ .../test/reporter/json_file_reporter_spec.ts | 10 ++++-- 4 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 modules/@angular/benchpress/src/reporter/util.ts diff --git a/modules/@angular/benchpress/src/reporter/console_reporter.ts b/modules/@angular/benchpress/src/reporter/console_reporter.ts index 86fbf92840..8a4a5198af 100644 --- a/modules/@angular/benchpress/src/reporter/console_reporter.ts +++ b/modules/@angular/benchpress/src/reporter/console_reporter.ts @@ -14,7 +14,8 @@ import {Math} from '../facade/math'; import {MeasureValues} from '../measure_values'; import {Reporter} from '../reporter'; import {SampleDescription} from '../sample_description'; -import {Statistic} from '../statistic'; + +import {formatNum, formatStats, sortedProps} from './util'; /** @@ -37,15 +38,6 @@ export class ConsoleReporter extends Reporter { return result + value; } - private static _formatNum(n: number) { return NumberWrapper.toFixed(n, 2); } - - private static _sortedProps(obj: {[key: string]: any}) { - var props: string[] = []; - StringMapWrapper.forEach(obj, (value, prop) => props.push(prop)); - props.sort(); - return props; - } - private _metricNames: string[]; constructor( @@ -53,14 +45,14 @@ export class ConsoleReporter extends Reporter { sampleDescription: SampleDescription, @Inject(ConsoleReporter.PRINT) private _print: Function) { super(); - this._metricNames = ConsoleReporter._sortedProps(sampleDescription.metrics); + this._metricNames = sortedProps(sampleDescription.metrics); this._printDescription(sampleDescription); } private _printDescription(sampleDescription: SampleDescription) { this._print(`BENCHMARK ${sampleDescription.id}`); this._print('Description:'); - var props = ConsoleReporter._sortedProps(sampleDescription.description); + var props = sortedProps(sampleDescription.description); props.forEach((prop) => { this._print(`- ${prop}: ${sampleDescription.description[prop]}`); }); this._print('Metrics:'); this._metricNames.forEach((metricName) => { @@ -74,7 +66,7 @@ export class ConsoleReporter extends Reporter { reportMeasureValues(measureValues: MeasureValues): Promise { var formattedValues = this._metricNames.map(metricName => { var value = measureValues.values[metricName]; - return ConsoleReporter._formatNum(value); + return formatNum(value); }); this._printStringRow(formattedValues); return Promise.resolve(null); @@ -82,15 +74,8 @@ export class ConsoleReporter extends Reporter { reportSample(completeSample: MeasureValues[], validSamples: MeasureValues[]): Promise { this._printStringRow(this._metricNames.map((_) => ''), '='); - this._printStringRow(this._metricNames.map(metricName => { - var samples = validSamples.map(measureValues => measureValues.values[metricName]); - var mean = Statistic.calculateMean(samples); - var cv = Statistic.calculateCoefficientOfVariation(samples, mean); - var formattedMean = ConsoleReporter._formatNum(mean); - // Note: Don't use the unicode character for +- as it might cause - // hickups for consoles... - return NumberWrapper.isNaN(cv) ? formattedMean : `${formattedMean}+-${Math.floor(cv)}%`; - })); + this._printStringRow( + this._metricNames.map(metricName => formatStats(validSamples, metricName))); return Promise.resolve(null); } diff --git a/modules/@angular/benchpress/src/reporter/json_file_reporter.ts b/modules/@angular/benchpress/src/reporter/json_file_reporter.ts index d1b4de712e..814aac37bc 100644 --- a/modules/@angular/benchpress/src/reporter/json_file_reporter.ts +++ b/modules/@angular/benchpress/src/reporter/json_file_reporter.ts @@ -14,6 +14,7 @@ import {MeasureValues} from '../measure_values'; import {Reporter} from '../reporter'; import {SampleDescription} from '../sample_description'; +import {formatStats, sortedProps} from './util'; /** @@ -34,10 +35,15 @@ export class JsonFileReporter extends Reporter { reportMeasureValues(measureValues: MeasureValues): Promise { return Promise.resolve(null); } reportSample(completeSample: MeasureValues[], validSample: MeasureValues[]): Promise { + const stats: {[key: string]: string} = {}; + sortedProps(this._description.metrics).forEach((metricName) => { + stats[metricName] = formatStats(validSample, metricName); + }); var content = Json.stringify({ 'description': this._description, + 'stats': stats, 'completeSample': completeSample, - 'validSample': validSample + 'validSample': validSample, }); var filePath = `${this._path}/${this._description.id}_${DateWrapper.toMillis(this._now())}.json`; diff --git a/modules/@angular/benchpress/src/reporter/util.ts b/modules/@angular/benchpress/src/reporter/util.ts new file mode 100644 index 0000000000..afe417c5ba --- /dev/null +++ b/modules/@angular/benchpress/src/reporter/util.ts @@ -0,0 +1,33 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {StringMapWrapper} from '../facade/collection'; +import {NumberWrapper} from '../facade/lang'; +import {MeasureValues} from '../measure_values'; +import {Statistic} from '../statistic'; + +export function formatNum(n: number) { + return NumberWrapper.toFixed(n, 2); +} + +export function sortedProps(obj: {[key: string]: any}) { + var props: string[] = []; + StringMapWrapper.forEach(obj, (value, prop) => props.push(prop)); + props.sort(); + return props; +} + +export function formatStats(validSamples: MeasureValues[], metricName: string): string { + var samples = validSamples.map(measureValues => measureValues.values[metricName]); + var mean = Statistic.calculateMean(samples); + var cv = Statistic.calculateCoefficientOfVariation(samples, mean); + var formattedMean = formatNum(mean); + // Note: Don't use the unicode character for +- as it might cause + // hickups for consoles... + return NumberWrapper.isNaN(cv) ? formattedMean : `${formattedMean}+-${Math.floor(cv)}%`; +} \ No newline at end of file diff --git a/modules/@angular/benchpress/test/reporter/json_file_reporter_spec.ts b/modules/@angular/benchpress/test/reporter/json_file_reporter_spec.ts index ab8ad75775..ba3f181d75 100644 --- a/modules/@angular/benchpress/test/reporter/json_file_reporter_spec.ts +++ b/modules/@angular/benchpress/test/reporter/json_file_reporter_spec.ts @@ -44,7 +44,7 @@ export function main() { sampleId: 'someId', descriptions: [{'a': 2}], path: 'somePath', - metrics: {'script': 'script time'} + metrics: {'a': 'script time', 'b': 'render time'} }) .reportSample( [mv(0, 0, {'a': 3, 'b': 6})], @@ -53,8 +53,12 @@ export function main() { expect(isPresent(loggedFile['filename'].match(regExp))).toBe(true); var parsedContent = Json.parse(loggedFile['content']); expect(parsedContent).toEqual({ - 'description': - {'id': 'someId', 'description': {'a': 2}, 'metrics': {'script': 'script time'}}, + 'description': { + 'id': 'someId', + 'description': {'a': 2}, + 'metrics': {'a': 'script time', 'b': 'render time'} + }, + 'stats': {'a': '4.00+-25%', 'b': '7.50+-20%'}, 'completeSample': [ {'timeStamp': '1970-01-01T00:00:00.000Z', 'runIndex': 0, 'values': {'a': 3, 'b': 6}} ],