-
Notifications
You must be signed in to change notification settings - Fork 0
/
benchmark-test.js
123 lines (102 loc) · 3.11 KB
/
benchmark-test.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* File provided by: https://github.com/ryyppy/re-compiler-benchmark-tool
*
* This is an attempt to provide quick metrics on the build time performance
* of a ReScript project.
*
* It requires following files in you package.json dependency list:
* - bs-platform
* - cloc (https://github.com/AlDanial/cloc)
*
* It also requires a bsconfig.json file to exist in the currently executing CWD.
* The script will automatically pick up your bsconfig.sources configuration to find
* all `.re` file occurrences and puts it in relation to the ReScript compiler build times.
*
* This script doesn't measure "world builds" (no -clean-world / -make-world).
*
*
* For Maintainers:
* -------------------
* No third-party libraries; only use language features available
* to NodeJS > v12
*/
const path = require("path");
const child_process = require("child_process");
const bsconfig = require(path.join(process.cwd(), "bsconfig.json"));
const BSB_BIN = "./node_modules/.bin/bsb";
const bsbClean = () => child_process.spawnSync(BSB_BIN, ["-clean"]);
// returns time { real, user, sys }
const timeBsbBuild = () => {
const ret = child_process.spawnSync("time", [BSB_BIN]);
if (ret.status !== 0) {
throw new Error(`bsb build failed with exit code ${ret.status}
fix the build issue before benchmarking
`);
}
// return output of the time function
const output = ret.stderr.toString();
const match = output.match(/\s+(.*)\sreal\s*(.*)\suser\s*(.*)\ssys.*/);
let time;
if (match) {
time = {
real: parseFloat(match[1]),
user: parseFloat(match[2]),
sys: parseFloat(match[3])
};
}
return time;
};
const getFileMetrics = () => {
const paths = bsconfig.sources.map(source => {
if (typeof source === "string") {
return source;
}
if (typeof source === "object") {
return source.dir;
}
});
const args = paths.concat(["--include-lang=ReasonML", "--json"]);
const ret = child_process.spawnSync("cloc", args);
if (ret.status !== 0) {
throw new Error(`cloc failed with exit code ${ret.status}`);
}
const out = JSON.parse(ret.stdout.toString());
return {
numberOfFiles: out.ReasonML.nFiles,
blankLines: out.ReasonML.blank,
commentLines: out.ReasonML.comment,
codeLines: out.ReasonML.code,
totalLines: out.header.n_lines
};
};
function main() {
const arg = process.argv[2];
if (arg === "--help" || arg === "-h") {
console.log("Runs simple benchmarks for a ReScript project");
return;
}
let asJson = true;
console.error("Capturing LOC / file numbers...");
const fileMetrics = getFileMetrics();
console.error("Cleaning the project first...");
bsbClean();
console.error("Measuring build performance...");
let buildTime = timeBsbBuild();
let locPerSec = Math.round(fileMetrics.totalLines / buildTime.real);
let result = {
fileMetrics,
buildTime,
results: {
locPerSec
}
};
if (asJson) {
console.log(JSON.stringify(result, null, 2));
}
// TODO: maybe add human readable format as an option?
}
try {
main();
} catch (err) {
console.error("Something went wrong: " + err);
process.exit(1);
}