9802bae15f
This ensures the impact test doesn't throw when testing against older commits that contain the bin files at their orignal locations.
151 lines
3.2 KiB
JavaScript
151 lines
3.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/* eslint camelcase:0, max-len:0, one-var:0 */
|
|
|
|
//
|
|
// Measures impact of a Git commit (or multiple commits) on generated parsers
|
|
// speed and size. Makes sense to use only on PEG.js git repository checkout.
|
|
//
|
|
|
|
"use strict";
|
|
|
|
let child_process = require("child_process");
|
|
let fs = require("fs");
|
|
let os = require("os");
|
|
let path = require("path");
|
|
let glob = require("glob");
|
|
|
|
// Current Working Directory
|
|
|
|
let cwd = path.join(__dirname, "..");
|
|
|
|
if (process.cwd() !== cwd) {
|
|
process.chdir(cwd);
|
|
}
|
|
|
|
// Execution Files
|
|
|
|
let PEGJS_BIN = "bin/peg.js";
|
|
let BENCHMARK_BIN = "test/benchmark/run";
|
|
|
|
if (!fs.existsSync(PEGJS_BIN)) {
|
|
PEGJS_BIN = "bin/pegjs";
|
|
}
|
|
|
|
if (!fs.existsSync(BENCHMARK_BIN)) {
|
|
BENCHMARK_BIN = "benchmark/run";
|
|
}
|
|
|
|
// Utils
|
|
|
|
let print = console.log;
|
|
|
|
function echo(message) {
|
|
process.stdout.write(message);
|
|
}
|
|
|
|
function exec(command) {
|
|
return child_process.execSync(command, { encoding: "utf8" });
|
|
}
|
|
|
|
function prepare(commit) {
|
|
exec(`git checkout --quiet "${commit}"`);
|
|
}
|
|
|
|
function runBenchmark() {
|
|
return parseFloat(
|
|
exec("node " + BENCHMARK_BIN)
|
|
// Split by table seprator, reverse and return the total bytes per second
|
|
.split("│")
|
|
.reverse()[1]
|
|
// Trim the whitespaces and remove ` kB/s` from the end
|
|
.trim()
|
|
.slice(0, -5)
|
|
);
|
|
}
|
|
|
|
function measureSpeed() {
|
|
return (runBenchmark() + runBenchmark() + runBenchmark() + runBenchmark() + runBenchmark() / 5).toFixed(2);
|
|
}
|
|
|
|
function measureSize() {
|
|
let size = 0;
|
|
|
|
glob.sync("examples/*.pegjs")
|
|
.forEach(example => {
|
|
exec(`node ${PEGJS_BIN} ${example}`);
|
|
example = example.slice(0, -5) + "js";
|
|
size += fs.statSync(example).size;
|
|
fs.unlinkSync(example);
|
|
});
|
|
|
|
return size;
|
|
}
|
|
|
|
function difference($1, $2) {
|
|
return (($2 / $1 - 1) * 100).toFixed(4);
|
|
}
|
|
|
|
// Prepare
|
|
|
|
let argv = process.argv.slice(2);
|
|
let commit_before, commit_after;
|
|
|
|
if (argv.length === 1) {
|
|
commit_before = argv[0] + "~1";
|
|
commit_after = argv[0];
|
|
} else if (argv.length === 2) {
|
|
commit_before = argv[0];
|
|
commit_after = argv[1];
|
|
} else {
|
|
print("Usage:");
|
|
print("");
|
|
print(" test/impact <commit>");
|
|
print(" test/impact <commit_before> <commit_after>");
|
|
print("");
|
|
print("Measures impact of a Git commit (or multiple commits) on generated parsers'");
|
|
print("speed and size. Makes sense to use only on PEG.js Git repository checkout.");
|
|
print("");
|
|
process.exit(1);
|
|
}
|
|
|
|
// Measure
|
|
|
|
let branch = exec("git rev-parse --abbrev-ref HEAD");
|
|
let speed1, size1, speed2, size2;
|
|
|
|
echo(`Measuring commit ${commit_before}...`);
|
|
prepare(commit_before);
|
|
speed1 = measureSpeed();
|
|
size1 = measureSize();
|
|
echo(" OK" + os.EOL);
|
|
|
|
echo(`Measuring commit ${commit_after}...`);
|
|
prepare(commit_after);
|
|
speed2 = measureSpeed();
|
|
size2 = measureSize();
|
|
echo(" OK" + os.EOL);
|
|
|
|
// Finish
|
|
|
|
prepare(branch);
|
|
|
|
print(`
|
|
test/impact ${commit_before} ${commit_after}
|
|
|
|
Speed impact
|
|
------------
|
|
Before: ${speed1} kB/s
|
|
After: ${speed2} kB/s
|
|
Difference: ${difference(parseFloat(speed1), parseFloat(speed2))}%
|
|
|
|
Size impact
|
|
-----------
|
|
Before: ${size1} b
|
|
After: ${size2} b
|
|
Difference: ${difference(size1, size2)}%
|
|
|
|
- Measured by /test/impact with Node.js ${process.version}
|
|
- Your system: ${os.type()} ${os.release()} ${os.arch()}.
|
|
`);
|