vesta
Version:
Simplify time measurements
180 lines (179 loc) • 5.97 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _myrmidon = require("myrmidon");
var _PlainReporter = _interopRequireDefault(require("./reporters/PlainReporter"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
class BaseBenchMark {
constructor({
counter,
shortSingleObservations = true
}) {
this._labels = [];
this.counter = counter;
this._start = this.counter.bench();
this._config = {
shortSingleObservations
};
this._iterations = [];
}
start(label, payload) {
const item = {
start: this.counter.bench(),
label
};
if (payload) item.payload = payload;
const len = this._labels.push(item);
return len - 1;
}
end(pointer) {
this._labels[pointer].end = this.counter.bench();
}
iteration() {
const benchmark = new this.constructor({
counter: this.counter,
...this._config
});
this._iterations.push(benchmark);
return benchmark;
}
sequence(label) {
const item = {
end: this.counter.bench(),
label,
sequence: true
};
this._labels.push(item);
}
calculateIntervals() {
this._labels.filter(l => l.sequence).forEach((item, index, sequence) => {
const startPoint = index === 0 ? this._start : sequence[index - 1].end;
item.bench = this.counter.diff(startPoint, item.end);
});
this._labels.filter(l => !l.sequence && l.start && l.end).forEach(item => {
item.bench = this.counter.diff(item.start, item.end);
});
}
_prepareMultiObservationReport(bench, metrics, report) {
for (const key of Object.keys(bench[0])) {
const arr = bench.map(b => b[key]);
report[key] = {};
this._prepareSingleObservationReport(arr, metrics, report[key]);
}
}
_prepareSingleObservationReport(bench, metrics, report) {
const metricNames = Object.keys(metrics).filter(metricName => metrics[metricName]);
for (const metricName of metricNames) {
report[metricName] = metrics[metricName](bench);
}
}
prepareReport(label, labels, {
metrics,
items
}) {
const filtered = labels.filter(ll => ll.label === label && (0, _myrmidon.isValue)(ll.bench));
if (filtered.length === 0) return;
const report = {
label
};
const bench = filtered.map(item => item.bench);
const multiObservation = (0, _myrmidon.isObject)(bench[0]);
if (filtered.length === 1 && this._config.shortSingleObservations) {
if (multiObservation) {
for (const key of Object.keys(bench[0])) {
report[key] = bench[0][key];
}
} else {
report.benchmark = bench[0];
}
return report;
}
if (multiObservation) {
this._prepareMultiObservationReport(bench, metrics, report);
} else {
this._prepareSingleObservationReport(bench, metrics, report);
}
for (const itemLabel of Object.keys(items)) {
if (!items[itemLabel]) continue;
report[itemLabel] = items[itemLabel](filtered, report);
}
return report;
}
calculate({
force = false,
metrics = {},
items = {}
} = {}) {
if (this._reports && !force) return this._reports;
this._reports = [];
const labels = [...this._labels];
for (const benchmark of this._iterations) {
for (const label of benchmark._labels) {
labels.push(label);
}
}
const labelsList = new Set(labels.map(l => l.label));
this.calculateIntervals();
this._iterations.forEach(b => b.calculateIntervals());
const mergedMetrics = {
...this.constructor.metrics,
...metrics
};
const mergedItems = {
...this.constructor.items,
...items
};
const metricsList = Object.keys(mergedMetrics);
const itemsList = Object.keys(mergedItems);
for (const label of labelsList) {
const report = this.prepareReport(label, labels, {
metrics: mergedMetrics,
items: mergedItems
});
if (!report) continue;
report._meta = {
metricsList,
itemsList
};
this._reports.push(report);
}
}
report(reporter = new _PlainReporter.default(), {
pretty = null
} = {}) {
this.calculate();
return reporter.run(this._reports, {
prettify: pretty && this.counter.constructor.prettify && this.prettify.bind(this, this.counter.constructor.prettify, (0, _myrmidon.isObject)(pretty) ? pretty : {})
});
}
prettify(prettifier, config, obj, meta) {
const res = {};
const {
exclude,
include = [...meta.metricsList, 'benchmark']
} = config;
const filter = new _myrmidon.InclusiveFilter({
include,
exclude
});
for (const key of Object.keys(obj)) {
if ((0, _myrmidon.isObject)(obj[key])) {
res[key] = this.prettify(prettifier, config, obj[key], meta);
continue;
}
res[key] = filter.run(key) ? prettifier(obj[key]) : obj[key];
}
return res;
}
}
exports.default = BaseBenchMark;
_defineProperty(BaseBenchMark, "metrics", {
total: arr => arr.length,
mean: arr => (0, _myrmidon.mean)(arr)
});
_defineProperty(BaseBenchMark, "items", {});