enumset32-benchmarks
Version:
Benchmarks for enumset32 vs other set implementations
161 lines (160 loc) • 6.18 kB
JavaScript
/*!
* Copyright (c) 2019 Justin Johansson
*/
import { XMLWriter } from './xmlwriter';
const svg = 'svg';
const desc = 'desc';
const g = 'g';
const path = 'path';
const rect = 'rect';
const text = 'text';
const xmlns = 'xmlns';
const clazz = 'class';
const preserveAspectRatio = 'preserveAspectRatio';
const style = 'style';
const transform = 'transform';
const viewBox = 'viewBox';
const d = 'd';
const height = 'height';
const width = 'width';
const x = 'x';
const y = 'y';
function X(_x) {
return _x;
}
function Y(_y) {
return 1000 - _y;
}
function calcBarColor(_y, _yMin, _ySpread) {
let _g = 120;
let _r = 40;
let _b = 180;
return `rgb(${_r},${_g},${_b})`;
}
export class SVGBarChart extends XMLWriter {
constructor(benchResults) {
super();
this.benchResults = benchResults;
this.startDocument()
.startElement(svg)
.attribute(xmlns, 'http://www.w3.org/2000/svg')
.attribute(style, 'width: 100%;')
.attribute(viewBox, '0 0 1600 1200')
.attribute(preserveAspectRatio, 'none')
.startElement(desc)
.text('Couchmark v0.1')
.endElement()
.startElement(style)
.text(`\
.stats { font: bold 48px helvetica, arial, sans-serif; }
.label { font: bold 40px arial, helvetica, sans-serif; }
.legend { font: 30px helvetica, arial, sans-serif; }
`)
.endElement()
.startElement(g)
.attribute(transform, 'translate(200,80) scale(0.8)')
.axes()
.domainMarks()
.rangeMarks()
.bars()
.endElement()
.startElement(g)
.attribute(transform, 'translate(100,260) scale(1.4)')
.summaries()
.endElement()
.endElement()
.endDocument();
}
axes() {
this.startElement(g)
.attribute(style, 'stroke-width: 5; stroke: gray;')
.startElement(path)
.attribute(d, `M ${X(0)} ${Y(0)} L ${X(1500)} ${Y(0)} Z`)
.endElement()
.startElement(path)
.attribute(d, `M ${X(0)} ${Y(1050)} L ${X(0)} ${Y(0)} Z`)
.endElement()
.endElement();
return this;
}
bars() {
let nResults = this.benchResults.length;
let refResult = this.benchResults[1];
let xStep = 1500 / 4;
let xBarWidth = Math.max(Math.min(xStep / 2, 100), 10);
let minOpsPerSecond2 = this.benchResults.reduce((mn, tst) => Math.min(mn, tst.opsPerSecond), +Infinity);
let maxOpsPerSecond2 = this.benchResults.reduce((mx, tst) => Math.max(mx, tst.opsPerSecond), -Infinity);
let opsPerSecondScale = 900 / refResult.opsPerSecond;
let opsPerSecondScale2 = 900 / maxOpsPerSecond2;
let yMin2 = minOpsPerSecond2 * opsPerSecondScale2;
let ySpread2 = (maxOpsPerSecond2 - minOpsPerSecond2) * (1000 / maxOpsPerSecond2);
for (let i = 0; i < nResults; ++i) {
let benchResult = this.benchResults[i];
let xx = (benchResult.testName.charCodeAt(0) - 0x41) * xStep + 100;
let yy = benchResult.opsPerSecond * opsPerSecondScale;
let yy2 = benchResult.opsPerSecond * opsPerSecondScale2;
this.startElement(rect)
.attribute(style, `fill: ${calcBarColor(yy2, yMin2, ySpread2)};`)
.attribute(x, X(xx))
.attribute(y, Y(yy))
.attribute(width, xBarWidth)
.attribute(height, yy)
.endElement()
.startElement(text)
.attribute(clazz, 'stats')
.attribute(style, 'fill: black; stroke: none; text-anchor: middle;')
.attribute(x, X(xx + xBarWidth / 2 + 10))
.attribute(y, Y(yy + 10))
.text((benchResult.opsPerSecond / 1000.0).toFixed(1) + ' Mops/sec')
.endElement()
.startElement(text)
.attribute(clazz, 'label')
.attribute(style, 'fill: black; stroke: none; text-anchor: middle;')
.attribute(x, X(xx + xBarWidth / 2))
.attribute(y, Y(-70))
.text(benchResult.testName.split('_')[1].replace(/\$/g, ' '))
.endElement();
}
return this;
}
domainMarks() {
return this;
}
rangeMarks() {
for (let yy = 0; yy <= 1000; yy += SVGBarChart.refHeightPerMille) {
if (yy > 0) {
this.startElement(g)
.attribute(style, 'fill: none; stroke: #B0B0B0; stroke-width: 2; stroke-dasharray: 2 4; text-anchor: end;')
.startElement(path)
.attribute(d, `M ${X(0)} ${Y(yy)} L ${X(1500)} ${Y(yy)} Z`)
.endElement()
.endElement();
}
}
return this;
}
summaries() {
let nResults = this.benchResults.length;
let minOpsPerSecond2 = this.benchResults.reduce((mn, tst) => Math.min(mn, tst.opsPerSecond), +Infinity);
let maxOpsPerSecond2 = this.benchResults.reduce((mx, tst) => Math.max(mx, tst.opsPerSecond), -Infinity);
let opsPerSecondScale2 = SVGBarChart.refHeightPerMille / maxOpsPerSecond2;
let yMin2 = minOpsPerSecond2 * opsPerSecondScale2;
let ySpread2 = (maxOpsPerSecond2 - minOpsPerSecond2) * (1000 / maxOpsPerSecond2);
for (let i = 0; i < nResults; ++i) {
let benchResult = this.benchResults[i];
let yy2 = benchResult.opsPerSecond * opsPerSecondScale2;
this.startElement(text)
.attribute(clazz, 'legend')
.attribute(style, `fill: ${calcBarColor(yy2, yMin2, ySpread2)}; stroke: none; text-anchor: start;`)
.attribute(x, X(0))
.attribute(y, Y(470 - i * 32))
.text(benchResult.summary
.replace(/\$/g, ' ')
.replace(/_/g, ' ')
.replace('ops/sec', 'Kops/sec'))
.endElement();
}
return this;
}
}
SVGBarChart.refHeightPerMille = 250;