feat(benchpress): also report the statistics in the generated file
This commit is contained in:
parent
942104d9ac
commit
873233e825
|
@ -14,7 +14,8 @@ import {Math} from '../facade/math';
|
||||||
import {MeasureValues} from '../measure_values';
|
import {MeasureValues} from '../measure_values';
|
||||||
import {Reporter} from '../reporter';
|
import {Reporter} from '../reporter';
|
||||||
import {SampleDescription} from '../sample_description';
|
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;
|
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[];
|
private _metricNames: string[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -53,14 +45,14 @@ export class ConsoleReporter extends Reporter {
|
||||||
sampleDescription: SampleDescription,
|
sampleDescription: SampleDescription,
|
||||||
@Inject(ConsoleReporter.PRINT) private _print: Function) {
|
@Inject(ConsoleReporter.PRINT) private _print: Function) {
|
||||||
super();
|
super();
|
||||||
this._metricNames = ConsoleReporter._sortedProps(sampleDescription.metrics);
|
this._metricNames = sortedProps(sampleDescription.metrics);
|
||||||
this._printDescription(sampleDescription);
|
this._printDescription(sampleDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _printDescription(sampleDescription: SampleDescription) {
|
private _printDescription(sampleDescription: SampleDescription) {
|
||||||
this._print(`BENCHMARK ${sampleDescription.id}`);
|
this._print(`BENCHMARK ${sampleDescription.id}`);
|
||||||
this._print('Description:');
|
this._print('Description:');
|
||||||
var props = ConsoleReporter._sortedProps(sampleDescription.description);
|
var props = sortedProps(sampleDescription.description);
|
||||||
props.forEach((prop) => { this._print(`- ${prop}: ${sampleDescription.description[prop]}`); });
|
props.forEach((prop) => { this._print(`- ${prop}: ${sampleDescription.description[prop]}`); });
|
||||||
this._print('Metrics:');
|
this._print('Metrics:');
|
||||||
this._metricNames.forEach((metricName) => {
|
this._metricNames.forEach((metricName) => {
|
||||||
|
@ -74,7 +66,7 @@ export class ConsoleReporter extends Reporter {
|
||||||
reportMeasureValues(measureValues: MeasureValues): Promise<any> {
|
reportMeasureValues(measureValues: MeasureValues): Promise<any> {
|
||||||
var formattedValues = this._metricNames.map(metricName => {
|
var formattedValues = this._metricNames.map(metricName => {
|
||||||
var value = measureValues.values[metricName];
|
var value = measureValues.values[metricName];
|
||||||
return ConsoleReporter._formatNum(value);
|
return formatNum(value);
|
||||||
});
|
});
|
||||||
this._printStringRow(formattedValues);
|
this._printStringRow(formattedValues);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
|
@ -82,15 +74,8 @@ export class ConsoleReporter extends Reporter {
|
||||||
|
|
||||||
reportSample(completeSample: MeasureValues[], validSamples: MeasureValues[]): Promise<any> {
|
reportSample(completeSample: MeasureValues[], validSamples: MeasureValues[]): Promise<any> {
|
||||||
this._printStringRow(this._metricNames.map((_) => ''), '=');
|
this._printStringRow(this._metricNames.map((_) => ''), '=');
|
||||||
this._printStringRow(this._metricNames.map(metricName => {
|
this._printStringRow(
|
||||||
var samples = validSamples.map(measureValues => measureValues.values[metricName]);
|
this._metricNames.map(metricName => formatStats(validSamples, 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)}%`;
|
|
||||||
}));
|
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {MeasureValues} from '../measure_values';
|
||||||
import {Reporter} from '../reporter';
|
import {Reporter} from '../reporter';
|
||||||
import {SampleDescription} from '../sample_description';
|
import {SampleDescription} from '../sample_description';
|
||||||
|
|
||||||
|
import {formatStats, sortedProps} from './util';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,10 +35,15 @@ export class JsonFileReporter extends Reporter {
|
||||||
reportMeasureValues(measureValues: MeasureValues): Promise<any> { return Promise.resolve(null); }
|
reportMeasureValues(measureValues: MeasureValues): Promise<any> { return Promise.resolve(null); }
|
||||||
|
|
||||||
reportSample(completeSample: MeasureValues[], validSample: MeasureValues[]): Promise<any> {
|
reportSample(completeSample: MeasureValues[], validSample: MeasureValues[]): Promise<any> {
|
||||||
|
const stats: {[key: string]: string} = {};
|
||||||
|
sortedProps(this._description.metrics).forEach((metricName) => {
|
||||||
|
stats[metricName] = formatStats(validSample, metricName);
|
||||||
|
});
|
||||||
var content = Json.stringify({
|
var content = Json.stringify({
|
||||||
'description': this._description,
|
'description': this._description,
|
||||||
|
'stats': stats,
|
||||||
'completeSample': completeSample,
|
'completeSample': completeSample,
|
||||||
'validSample': validSample
|
'validSample': validSample,
|
||||||
});
|
});
|
||||||
var filePath =
|
var filePath =
|
||||||
`${this._path}/${this._description.id}_${DateWrapper.toMillis(this._now())}.json`;
|
`${this._path}/${this._description.id}_${DateWrapper.toMillis(this._now())}.json`;
|
||||||
|
|
|
@ -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)}%`;
|
||||||
|
}
|
|
@ -44,7 +44,7 @@ export function main() {
|
||||||
sampleId: 'someId',
|
sampleId: 'someId',
|
||||||
descriptions: [{'a': 2}],
|
descriptions: [{'a': 2}],
|
||||||
path: 'somePath',
|
path: 'somePath',
|
||||||
metrics: {'script': 'script time'}
|
metrics: {'a': 'script time', 'b': 'render time'}
|
||||||
})
|
})
|
||||||
.reportSample(
|
.reportSample(
|
||||||
[mv(0, 0, {'a': 3, 'b': 6})],
|
[mv(0, 0, {'a': 3, 'b': 6})],
|
||||||
|
@ -53,8 +53,12 @@ export function main() {
|
||||||
expect(isPresent(loggedFile['filename'].match(regExp))).toBe(true);
|
expect(isPresent(loggedFile['filename'].match(regExp))).toBe(true);
|
||||||
var parsedContent = Json.parse(loggedFile['content']);
|
var parsedContent = Json.parse(loggedFile['content']);
|
||||||
expect(parsedContent).toEqual({
|
expect(parsedContent).toEqual({
|
||||||
'description':
|
'description': {
|
||||||
{'id': 'someId', 'description': {'a': 2}, 'metrics': {'script': 'script time'}},
|
'id': 'someId',
|
||||||
|
'description': {'a': 2},
|
||||||
|
'metrics': {'a': 'script time', 'b': 'render time'}
|
||||||
|
},
|
||||||
|
'stats': {'a': '4.00+-25%', 'b': '7.50+-20%'},
|
||||||
'completeSample': [
|
'completeSample': [
|
||||||
{'timeStamp': '1970-01-01T00:00:00.000Z', 'runIndex': 0, 'values': {'a': 3, 'b': 6}}
|
{'timeStamp': '1970-01-01T00:00:00.000Z', 'runIndex': 0, 'values': {'a': 3, 'b': 6}}
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue