Move bench results to own folder and generate per-test graphs
This commit is contained in:
parent
3e7072c7e4
commit
e683eed0b5
|
@ -17,7 +17,7 @@ Available as:
|
|||
|
||||
Speed and effectiveness of Node.js version compared to [html-minfier](https://github.com/kangax/html-minifier) and [minimize](https://github.com/Swaagie/minimize). See [bench](./bench) folder for more details.
|
||||
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers" src="./bench/speed.png"> <img width="435" alt="Chart showing effectiveness of HTML minifiers" src="./bench/minification.png">
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers" src="./bench/results/average-speeds.png"> <img width="435" alt="Chart showing effectiveness of HTML minifiers" src="./bench/results/average-sizes.png">
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
const benchmark = require('benchmark');
|
||||
const childProcess = require('child_process');
|
||||
const fs = require('fs');
|
||||
const minimist = require('minimist');
|
||||
const path = require('path');
|
||||
const programs = require('./minifiers');
|
||||
const minifiers = require('./minifiers');
|
||||
const results = require('./results');
|
||||
const tests = require('./tests');
|
||||
|
||||
const args = minimist(process.argv.slice(2));
|
||||
|
@ -59,24 +59,24 @@ const setSize = (program, test, result) => {
|
|||
|
||||
// Run once to set sizes.
|
||||
for (const t of tests) {
|
||||
for (const p of Object.keys(programs)) {
|
||||
for (const m of Object.keys(minifiers)) {
|
||||
try {
|
||||
setSize(p, t.name, programs[p](t.contentAsString, t.contentAsBuffer).length);
|
||||
setSize(m, t.name, minifiers[m](t.contentAsString, t.contentAsBuffer).length);
|
||||
} catch (err) {
|
||||
console.error(`Failed to run ${p} on test ${t.name}:`);
|
||||
console.error(`Failed to run ${m} on test ${t.name}:`);
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(path.join(__dirname, 'minification.json'), JSON.stringify(sizes, null, 2));
|
||||
results.writeSizeResults(sizes);
|
||||
|
||||
const runTest = test => new Promise((resolve, reject) => {
|
||||
// Run JS libraries.
|
||||
const suite = new benchmark.Suite();
|
||||
for (const p of Object.keys(programs)) {
|
||||
suite.add(p, () => {
|
||||
programs[p](test.contentAsString, test.contentAsBuffer);
|
||||
for (const m of Object.keys(minifiers)) {
|
||||
suite.add(m, () => {
|
||||
minifiers[m](test.contentAsString, test.contentAsBuffer);
|
||||
});
|
||||
}
|
||||
suite
|
||||
|
@ -87,7 +87,7 @@ const runTest = test => new Promise((resolve, reject) => {
|
|||
});
|
||||
|
||||
(async () => {
|
||||
const results = fromEntries(tests.map(t => [t.name, {}]));
|
||||
const speeds = fromEntries(tests.map(t => [t.name, {}]));
|
||||
|
||||
// Run Rust library.
|
||||
if (shouldRunRust) {
|
||||
|
@ -96,12 +96,12 @@ const runTest = test => new Promise((resolve, reject) => {
|
|||
'--iterations', 512,
|
||||
'--tests', path.join(__dirname, 'tests'),
|
||||
))) {
|
||||
Object.assign(results[testName], {hyperbuild: testOps});
|
||||
Object.assign(speeds[testName], {hyperbuild: testOps});
|
||||
}
|
||||
}
|
||||
|
||||
for (const t of tests) {
|
||||
Object.assign(results[t.name], await runTest(t));
|
||||
Object.assign(speeds[t.name], await runTest(t));
|
||||
}
|
||||
fs.writeFileSync(path.join(__dirname, 'speed.json'), JSON.stringify(results, null, 2));
|
||||
results.writeSpeedResults(speeds);
|
||||
})();
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
const chartjs = require('chartjs-node');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const tests = require('./tests');
|
||||
const results = require('./results');
|
||||
|
||||
const colours = {
|
||||
'hyperbuild': '#041f60',
|
||||
|
@ -10,8 +8,6 @@ const colours = {
|
|||
'html-minifier': '#2ca02c',
|
||||
};
|
||||
|
||||
const programNames = ['minimize', 'html-minifier', 'hyperbuild-nodejs'];
|
||||
|
||||
const chartOptions = (title, displayLegend, yTick = t => t) => ({
|
||||
options: {
|
||||
title: {
|
||||
|
@ -45,67 +41,73 @@ const chartOptions = (title, displayLegend, yTick = t => t) => ({
|
|||
legend: {
|
||||
display: displayLegend,
|
||||
labels: {
|
||||
fontFamily: 'Arial, sans-serif',
|
||||
fontColor: '#000',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const renderChart = async (file, cfg) => {
|
||||
const renderChart = async (cfg) => {
|
||||
const chart = new chartjs(900, 650);
|
||||
await chart.drawChart(cfg);
|
||||
await chart.writeImageToFile('image/png', path.join(__dirname, `${file}.png`));
|
||||
return chart.getImageBuffer('image/png');
|
||||
};
|
||||
|
||||
(async () => {
|
||||
const testNames = tests.map(t => t.name).sort();
|
||||
|
||||
const speedResults = JSON.parse(fs.readFileSync(path.join(__dirname, 'speed.json'), 'utf8'));
|
||||
const speedData = programNames.map(program => [
|
||||
program,
|
||||
testNames
|
||||
// Get OP/s for each test.
|
||||
.map(test => speedResults[test][program] / speedResults[test]['hyperbuild-nodejs'])
|
||||
// Sum all test OP/s.
|
||||
.reduce((sum, c) => sum + c)
|
||||
// Divide by tests count to get average OP/s.
|
||||
/ testNames.length,
|
||||
]).sort((a, b) => a[1] - b[1]);
|
||||
await renderChart('speed', {
|
||||
const averageSpeeds = results.getSpeedResults().getAverageRelativeSpeedPerMinifier('hyperbuild-nodejs');
|
||||
results.writeAverageSpeedsGraph(await renderChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: speedData.map(([n]) => n),
|
||||
// Node.js version is close enough to Rust version, so leave out Rust results.
|
||||
// Include it this if this situation changes.
|
||||
labels: averageSpeeds.map(([n]) => n),
|
||||
datasets: [{
|
||||
label: 'Average relative OP/s',
|
||||
backgroundColor: '#1f77b4',
|
||||
data: speedData.map(([_, v]) => v),
|
||||
data: averageSpeeds.map(([_, v]) => v),
|
||||
}],
|
||||
},
|
||||
...chartOptions('Average operations per second (higher is better)', false, tick => `${tick * 100}%`),
|
||||
});
|
||||
}));
|
||||
|
||||
const sizes = JSON.parse(fs.readFileSync(path.join(__dirname, 'minification.json'), 'utf8'));
|
||||
const sizeData = programNames.map(program => [
|
||||
program,
|
||||
testNames
|
||||
.map(test => sizes[test][program].relative)
|
||||
.reduce((sum, c) => sum + c)
|
||||
/ testNames.length,
|
||||
]).sort((a, b) => b[1] - a[1]);
|
||||
await renderChart('minification', {
|
||||
const speeds = results.getSpeedResults().getRelativeFileSpeedsPerMinifier('hyperbuild-nodejs');
|
||||
results.writeSpeedsGraph(await renderChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: speeds[0][1].map(([n]) => n),
|
||||
datasets: speeds.map(([minifier, fileSpeeds]) => ({
|
||||
label: minifier,
|
||||
backgroundColor: colours[minifier],
|
||||
data: fileSpeeds.map(([_, speed]) => speed),
|
||||
})),
|
||||
},
|
||||
...chartOptions('Operations per second (higher is better)', true, tick => `${tick * 100}%`),
|
||||
}));
|
||||
|
||||
const averageSizes = results.getSizeResults().getAverageRelativeSizePerMinifier();
|
||||
results.writeAverageSizesGraph(await renderChart({
|
||||
type: 'bar',
|
||||
scaleFontColor: 'red',
|
||||
data: {
|
||||
labels: sizeData.map(([n]) => n),
|
||||
labels: averageSizes.map(([n]) => n),
|
||||
datasets: [{
|
||||
label: 'Average minified size',
|
||||
backgroundColor: '#2ca02c',
|
||||
data: sizeData.map(([_, v]) => v),
|
||||
data: averageSizes.map(([_, v]) => v),
|
||||
}],
|
||||
},
|
||||
...chartOptions('Average minified size (lower is better)', false, tick => `${tick * 100}%`),
|
||||
});
|
||||
}));
|
||||
|
||||
const sizes = results.getSizeResults().getRelativeFileSizesPerMinifier();
|
||||
results.writeSizesGraph(await renderChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: sizes[0][1].map(([n]) => n),
|
||||
datasets: sizes.map(([minifier, fileSizes]) => ({
|
||||
label: minifier,
|
||||
backgroundColor: colours[minifier],
|
||||
data: fileSizes.map(([_, size]) => size),
|
||||
})),
|
||||
},
|
||||
...chartOptions('Minified size (lower is better)', true, tick => `${tick * 100}%`),
|
||||
}));
|
||||
})();
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
const {join} = require('path');
|
||||
const {readFileSync, writeFileSync} = require('fs');
|
||||
const minifiers = require('./minifiers');
|
||||
const tests = require('./tests');
|
||||
|
||||
const RESULTS_DIR = join(__dirname, 'results');
|
||||
const SPEEDS_JSON = join(RESULTS_DIR, 'speeds.json');
|
||||
const SPEEDS_GRAPH = join(RESULTS_DIR, 'speeds.png');
|
||||
const AVERAGE_SPEEDS_GRAPH = join(RESULTS_DIR, 'average-speeds.png');
|
||||
const SIZES_JSON = join(RESULTS_DIR, 'sizes.json');
|
||||
const SIZES_GRAPH = join(RESULTS_DIR, 'sizes.png');
|
||||
const AVERAGE_SIZES_GRAPH = join(RESULTS_DIR, 'average-sizes.png');
|
||||
|
||||
const minifierNames = Object.keys(minifiers);
|
||||
const testNames = tests.map(t => t.name);
|
||||
|
||||
module.exports = {
|
||||
writeSpeedResults(speeds) {
|
||||
writeFileSync(SPEEDS_JSON, JSON.stringify(speeds, null, 2));
|
||||
},
|
||||
writeSizeResults(sizes) {
|
||||
writeFileSync(SIZES_JSON, JSON.stringify(sizes, null, 2));
|
||||
},
|
||||
writeAverageSpeedsGraph(data) {
|
||||
writeFileSync(AVERAGE_SPEEDS_GRAPH, data);
|
||||
},
|
||||
writeSpeedsGraph(data) {
|
||||
writeFileSync(SPEEDS_GRAPH, data);
|
||||
},
|
||||
writeAverageSizesGraph(data) {
|
||||
writeFileSync(AVERAGE_SIZES_GRAPH, data);
|
||||
},
|
||||
writeSizesGraph(data) {
|
||||
writeFileSync(SIZES_GRAPH, data);
|
||||
},
|
||||
getSpeedResults() {
|
||||
const data = JSON.parse(readFileSync(SPEEDS_JSON, 'utf8'));
|
||||
|
||||
return {
|
||||
// Get minifier-speed pairs sorted by speed ascending.
|
||||
getAverageRelativeSpeedPerMinifier(baselineMinifier) {
|
||||
return minifierNames.map(minifier => [
|
||||
minifier,
|
||||
testNames
|
||||
// Get OP/s for each test.
|
||||
.map(test => data[test][minifier] / data[test][baselineMinifier])
|
||||
// Sum all test OP/s.
|
||||
.reduce((sum, c) => sum + c)
|
||||
// Divide by tests count to get average OP/s.
|
||||
/ testNames.length,
|
||||
]).sort((a, b) => a[1] - b[1]);
|
||||
},
|
||||
// Get minifier-speeds pairs.
|
||||
getRelativeFileSpeedsPerMinifier(baselineMinifier) {
|
||||
return minifierNames.map(minifier => [
|
||||
minifier,
|
||||
testNames.map(test => [test, data[test][minifier] / data[test][baselineMinifier]]),
|
||||
]);
|
||||
},
|
||||
};
|
||||
},
|
||||
getSizeResults() {
|
||||
const data = JSON.parse(readFileSync(SIZES_JSON, 'utf8'));
|
||||
|
||||
return {
|
||||
// Get minifier-size pairs sorted by size descending.
|
||||
getAverageRelativeSizePerMinifier() {
|
||||
return minifierNames.map(minifier => [
|
||||
minifier,
|
||||
testNames
|
||||
.map(test => data[test][minifier].relative)
|
||||
.reduce((sum, c) => sum + c)
|
||||
/ testNames.length,
|
||||
]).sort((a, b) => b[1] - a[1]);
|
||||
},
|
||||
// Get minifier-sizes pairs.
|
||||
getRelativeFileSizesPerMinifier() {
|
||||
return minifierNames.map(minifier => [
|
||||
minifier,
|
||||
testNames.map(test => [test, data[test][minifier].relative]),
|
||||
]);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
Binary file not shown.
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
@ -5,8 +5,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 353501,
|
||||
"relative": 0.9584752288403974
|
||||
"absolute": 353722,
|
||||
"relative": 0.9590744436250054
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 355185,
|
||||
|
@ -23,8 +23,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 231706,
|
||||
"relative": 0.9410641832204925
|
||||
"absolute": 231728,
|
||||
"relative": 0.9411535352961006
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 234306,
|
||||
|
@ -59,8 +59,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 270833,
|
||||
"relative": 0.8743825506389188
|
||||
"absolute": 272551,
|
||||
"relative": 0.8799291022851277
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 277911,
|
||||
|
@ -77,8 +77,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 79806,
|
||||
"relative": 0.9430212222904949
|
||||
"absolute": 80117,
|
||||
"relative": 0.9466961289407761
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 81446,
|
||||
|
@ -95,8 +95,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 5744290,
|
||||
"relative": 0.9094262560459782
|
||||
"absolute": 5761075,
|
||||
"relative": 0.9120836287948699
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 5785725,
|
||||
|
@ -113,8 +113,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 196577,
|
||||
"relative": 0.9963860307162046
|
||||
"absolute": 196585,
|
||||
"relative": 0.996426580161184
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 196600,
|
||||
|
@ -131,8 +131,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 28154,
|
||||
"relative": 0.8275476911319479
|
||||
"absolute": 28203,
|
||||
"relative": 0.8289879780135798
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 29086,
|
||||
|
@ -149,8 +149,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 1263682,
|
||||
"relative": 0.9967251233205608
|
||||
"absolute": 1263691,
|
||||
"relative": 0.9967322220416869
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 1263150,
|
||||
|
@ -167,8 +167,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 648004,
|
||||
"relative": 0.9945163810263407
|
||||
"absolute": 648011,
|
||||
"relative": 0.994527124192536
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 647822,
|
||||
|
@ -185,8 +185,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 86693,
|
||||
"relative": 0.7724652273476552
|
||||
"absolute": 87177,
|
||||
"relative": 0.7767778381701699
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 88366,
|
||||
|
@ -203,8 +203,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 272480,
|
||||
"relative": 0.8645931830152878
|
||||
"absolute": 272916,
|
||||
"relative": 0.8659766336457732
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 266639,
|
||||
|
@ -221,8 +221,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 1319432,
|
||||
"relative": 0.9350014704267072
|
||||
"absolute": 1320740,
|
||||
"relative": 0.9359283707317765
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 1327244,
|
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"Amazon": {
|
||||
"hyperbuild-nodejs": 496.69767089636576,
|
||||
"html-minifier": 36.22644969886744,
|
||||
"minimize": 113.46511363852734
|
||||
},
|
||||
"BBC": {
|
||||
"hyperbuild-nodejs": 530.7581308772171,
|
||||
"html-minifier": 49.92474956429014,
|
||||
"minimize": 160.83375271616242
|
||||
},
|
||||
"Bing": {
|
||||
"hyperbuild-nodejs": 2143.2738405584682,
|
||||
"html-minifier": 224.01168295253845,
|
||||
"minimize": 548.4301545148764
|
||||
},
|
||||
"Bootstrap": {
|
||||
"hyperbuild-nodejs": 271.9278016916176,
|
||||
"html-minifier": 8.063475087253176,
|
||||
"minimize": 22.267478295105477
|
||||
},
|
||||
"Coding Horror": {
|
||||
"hyperbuild-nodejs": 1023.4279917437968,
|
||||
"html-minifier": 48.701642742613835,
|
||||
"minimize": 186.3127301413615
|
||||
},
|
||||
"ECMA-262": {
|
||||
"hyperbuild-nodejs": 15.516204982806318,
|
||||
"html-minifier": 0.44813616072549084,
|
||||
"minimize": 1.3379096629237164
|
||||
},
|
||||
"Google": {
|
||||
"hyperbuild-nodejs": 1828.0608850870312,
|
||||
"html-minifier": 243.05811241714517,
|
||||
"minimize": 575.3743754787441
|
||||
},
|
||||
"Hacker News": {
|
||||
"hyperbuild-nodejs": 2098.1972805031955,
|
||||
"html-minifier": 73.59734557807897,
|
||||
"minimize": 271.03920934848253
|
||||
},
|
||||
"NY Times": {
|
||||
"hyperbuild-nodejs": 264.01040398999527,
|
||||
"html-minifier": 36.483800875972946,
|
||||
"minimize": 86.74545622195224
|
||||
},
|
||||
"Reddit": {
|
||||
"hyperbuild-nodejs": 402.9146825613306,
|
||||
"html-minifier": 44.44689052201565,
|
||||
"minimize": 124.65890370904272
|
||||
},
|
||||
"Stack Overflow": {
|
||||
"hyperbuild-nodejs": 822.1712538713629,
|
||||
"html-minifier": 40.65363487825213,
|
||||
"minimize": 158.40795613979014
|
||||
},
|
||||
"Twitter": {
|
||||
"hyperbuild-nodejs": 279.88535523093344,
|
||||
"html-minifier": 36.231829473085334,
|
||||
"minimize": 167.45777652008428
|
||||
},
|
||||
"Wikipedia": {
|
||||
"hyperbuild-nodejs": 54.31371594883309,
|
||||
"html-minifier": 2.808823542495513,
|
||||
"minimize": 8.687326663074192
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
10
bench/run.js
10
bench/run.js
|
@ -1,17 +1,17 @@
|
|||
const fs = require('fs');
|
||||
const mkdirp = require('mkdirp');
|
||||
const path = require('path');
|
||||
const programs = require('./minifiers');
|
||||
const minifiers = require('./minifiers');
|
||||
const tests = require('./tests');
|
||||
|
||||
for (const t of tests) {
|
||||
for (const p of Object.keys(programs)) {
|
||||
for (const m of Object.keys(minifiers)) {
|
||||
try {
|
||||
const minPath = path.join(__dirname, 'min', p, `${t.name}.html`);
|
||||
const minPath = path.join(__dirname, 'min', m, `${t.name}.html`);
|
||||
mkdirp.sync(path.dirname(minPath));
|
||||
fs.writeFileSync(minPath, programs[p](t.contentAsString, t.contentAsBuffer));
|
||||
fs.writeFileSync(minPath, minifiers[m](t.contentAsString, t.contentAsBuffer));
|
||||
} catch (err) {
|
||||
console.error(`Failed to run ${p} on test ${t.name}:`);
|
||||
console.error(`Failed to run ${m} on test ${t.name}:`);
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
{
|
||||
"Amazon": {
|
||||
"hyperbuild-nodejs": 499.9428905642954,
|
||||
"html-minifier": 36.3036627447208,
|
||||
"minimize": 113.33527430279831
|
||||
},
|
||||
"BBC": {
|
||||
"hyperbuild-nodejs": 534.5358584753244,
|
||||
"html-minifier": 49.23362197831472,
|
||||
"minimize": 161.96803168572117
|
||||
},
|
||||
"Bing": {
|
||||
"hyperbuild-nodejs": 2137.27013270331,
|
||||
"html-minifier": 223.08512226985184,
|
||||
"minimize": 550.9181761277221
|
||||
},
|
||||
"Bootstrap": {
|
||||
"hyperbuild-nodejs": 277.1391080206004,
|
||||
"html-minifier": 8.043255283692064,
|
||||
"minimize": 22.245439492019898
|
||||
},
|
||||
"Coding Horror": {
|
||||
"hyperbuild-nodejs": 1096.4910673601032,
|
||||
"html-minifier": 49.83595257976626,
|
||||
"minimize": 188.32749988717788
|
||||
},
|
||||
"ECMA-262": {
|
||||
"hyperbuild-nodejs": 16.200240897950334,
|
||||
"html-minifier": 0.45522858062374655,
|
||||
"minimize": 1.3356053866389666
|
||||
},
|
||||
"Google": {
|
||||
"hyperbuild-nodejs": 1832.4626475818236,
|
||||
"html-minifier": 242.1462398878334,
|
||||
"minimize": 564.1884364813526
|
||||
},
|
||||
"Hacker News": {
|
||||
"hyperbuild-nodejs": 2127.8084431041266,
|
||||
"html-minifier": 74.78979361035866,
|
||||
"minimize": 272.3995630011103
|
||||
},
|
||||
"NY Times": {
|
||||
"hyperbuild-nodejs": 265.55362689112695,
|
||||
"html-minifier": 37.146711151201565,
|
||||
"minimize": 87.7133467873164
|
||||
},
|
||||
"Reddit": {
|
||||
"hyperbuild-nodejs": 391.75000439723124,
|
||||
"html-minifier": 45.067854272152125,
|
||||
"minimize": 125.87983932864549
|
||||
},
|
||||
"Stack Overflow": {
|
||||
"hyperbuild-nodejs": 818.3755008258345,
|
||||
"html-minifier": 41.43093414076361,
|
||||
"minimize": 159.71387801780298
|
||||
},
|
||||
"Twitter": {
|
||||
"hyperbuild-nodejs": 274.57816497268476,
|
||||
"html-minifier": 36.94949014023178,
|
||||
"minimize": 168.81796573617953
|
||||
},
|
||||
"Wikipedia": {
|
||||
"hyperbuild-nodejs": 54.852210553433345,
|
||||
"html-minifier": 2.821530343574604,
|
||||
"minimize": 8.66394750522524
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue