-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbenchmark.js
83 lines (65 loc) · 3.53 KB
/
benchmark.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
"use strict";
const compile = require('./index');
const fs = require('fs');
const path = require('path');
const samples = path.join(__dirname, 'samples');
const time = parseInt(process.argv[2] / 2) || 5000; // ms/test
function human(size) {
const UNIT = [ ' \x1b[2;37mB', '\x1b[2;32mkB', '\x1b[2;36mMB', '\x1b[2;34mGB', '\x1b[2;31mTB' ];
const exp = size ? Math.min(Math.floor(Math.log10(size) / 3), UNIT.length - 1) : 0;
size /= Math.pow(10, 3 * exp);
size = size.toLocaleString(undefined, { maximumFractionDigits: 1, minimumFractionDigits: 1 });
return `${size} ${UNIT[exp]}`;
}
// eslint-disable-next-line no-console
console.log(`
┌────────────────┬───────────┬────────────┬──────────┬──────────┬────────────┐
│ Test │ Compile │ Rendered │ Template │ Output │ Throughput │
├────────────────┼───────────┼────────────┼──────────┼──────────┼────────────┤`);
// eslint-disable-next-line no-sync
fs.readdirSync(samples)
.map((f) => f.match(/^(.*)\.what$/))
.filter((m) => (m))
.reduce((all, [ , t ]) => {
// eslint-disable-next-line global-require
const input = require(path.join(samples, `${t}.in.js`));
// eslint-disable-next-line no-sync
const what = fs.readFileSync(path.join(samples, `${t}.what`), 'utf8');
let insize = Buffer.from(what, 'utf8').length;
let outsize = Buffer.from(compile(what)(input()), 'utf8').length;
let compiled = 0, rendered = 0;
return all.then(() => new Promise((done) => {
const start = new Date();
let running = setImmediate(function run() {
compile(what); compiled++; running = setImmediate(run);
});
setTimeout(() => { clearImmediate(running); compiled /= new Date() - start; done(); }, time);
})).then(() => new Promise((done) => {
const template = compile(what);
const start = new Date();
let running = setImmediate(function run() {
template(input()); rendered++; running = setImmediate(run);
});
setTimeout(() => { clearImmediate(running); rendered /= new Date() - start; done(); }, time);
})).then(() => {
let through = human(1000 * outsize * rendered).padStart(15);
compiled = parseInt(1000 * compiled).toLocaleString().padStart(6);
rendered = parseInt(1000 * rendered).toLocaleString().padStart(7);
insize = human(insize).toLocaleString().padStart(15);
outsize = human(outsize).toLocaleString().padStart(15);
t = `\x1b[34m${t.padEnd(14)}`;
compiled = `\x1b[1;36m${compiled} \x1b[2;35m/s`;
rendered = `\x1b[1;32m${rendered} \x1b[2;35m/s`;
insize = `\x1b[2;37m${insize}`;
outsize = `\x1b[2;37m${outsize}`;
through = `\x1b[2;33m${through}/s`;
const row = [ t, compiled, rendered, insize, outsize, through ];
const BAR = '\x1b[0m│';
// eslint-disable-next-line no-console
console.log(`${BAR} ${row.join(` ${BAR} `)} ${BAR}`);
});
}, Promise.resolve())
.then(() => {
// eslint-disable-next-line no-console
console.log('└────────────────┴───────────┴────────────┴──────────┴──────────┴────────────┘\n');
});