Skip to content

Commit 4453767

Browse files
committed
Benchmark: replace shell scripts with JS code
1 parent 7cfd686 commit 4453767

File tree

1 file changed

+55
-52
lines changed

1 file changed

+55
-52
lines changed

resources/benchmark.js

+55-52
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,21 @@ const { Suite } = require('benchmark');
99
const beautifyBenchmark = require('beautify-benchmark');
1010
const { execSync } = require('child_process');
1111
const os = require('os');
12+
const fs = require('fs');
1213
const path = require('path');
1314

1415
// Like build:cjs, but includes __tests__ and copies other files.
1516
const BUILD_CMD = 'babel src --optional runtime --copy-files --out-dir dist/';
1617
const LOCAL = 'local';
17-
const LOCAL_DIR = path.join(__dirname, '../');
18-
const TEMP_DIR = os.tmpdir();
18+
function LOCAL_DIR(...paths) {
19+
return path.join(__dirname, '..', ...paths);
20+
}
21+
function TEMP_DIR(...paths) {
22+
return path.join(os.tmpdir(), 'graphql-js-benchmark', ...paths);
23+
}
1924

2025
// Returns the complete git hash for a given git revision reference.
2126
function hashForRevision(revision) {
22-
if (revision === LOCAL) {
23-
return revision;
24-
}
2527
const out = execSync(`git rev-parse "${revision}"`, { encoding: 'utf8' });
2628
const match = /[0-9a-f]{8,40}/.exec(out);
2729
if (!match) {
@@ -30,54 +32,47 @@ function hashForRevision(revision) {
3032
return match[0];
3133
}
3234

33-
// Returns the temporary directory which hosts the files for this git hash.
34-
function dirForHash(hash) {
35-
if (hash === LOCAL) {
36-
return path.join(__dirname, '../');
37-
}
38-
return path.join(TEMP_DIR, 'graphql-js-benchmark', hash);
39-
}
40-
41-
// Build a benchmarkable environment for the given revision.
35+
// Build a benchmarkable environment for the given revision
36+
// and returns path to its 'dist' directory.
4237
function prepareRevision(revision) {
4338
console.log(`🍳 Preparing ${revision}...`);
44-
const hash = hashForRevision(revision);
45-
const dir = dirForHash(hash);
46-
if (hash === LOCAL) {
47-
execSync(`(cd "${dir}" && yarn run ${BUILD_CMD})`);
39+
40+
if (revision === LOCAL) {
41+
execSync(`yarn run ${BUILD_CMD}`);
42+
return LOCAL_DIR('dist');
4843
} else {
49-
execSync(`
50-
if [ ! -d "${dir}" ]; then
51-
mkdir -p "${dir}" &&
52-
git archive "${hash}" | tar -xC "${dir}" &&
53-
(cd "${dir}" && yarn install);
54-
fi &&
55-
# Copy in local tests so the same logic applies to each revision.
56-
for file in $(cd "${LOCAL_DIR}src"; find . -path '*/__tests__/*');
57-
do cp "${LOCAL_DIR}src/$file" "${dir}/src/$file";
58-
done &&
59-
(cd "${dir}" && yarn run ${BUILD_CMD})
60-
`);
44+
if (!fs.existsSync(TEMP_DIR())) {
45+
fs.mkdirSync(TEMP_DIR());
46+
}
47+
48+
const hash = hashForRevision(revision);
49+
const dir = TEMP_DIR(hash);
50+
51+
if (!fs.existsSync(dir)) {
52+
fs.mkdirSync(dir);
53+
execSync(`git archive "${hash}" | tar -xC "${dir}"`);
54+
execSync('yarn install', { cwd: dir });
55+
}
56+
for (const file of findFiles(LOCAL_DIR('src'), '*/__tests__/*')) {
57+
const from = LOCAL_DIR('src', file);
58+
const to = path.join(dir, 'src', file);
59+
fs.copyFileSync(from, to);
60+
}
61+
execSync(`yarn run ${BUILD_CMD}`, { cwd: dir });
62+
63+
return path.join(dir, 'dist');
6164
}
6265
}
6366

64-
// Find all benchmark tests to be run.
65-
function findBenchmarks() {
66-
const out = execSync(
67-
`(cd ${LOCAL_DIR}src; find . -path '*/__tests__/*-benchmark.js')`,
68-
{ encoding: 'utf8' },
69-
);
67+
function findFiles(cwd, pattern) {
68+
const out = execSync(`find . -path '${pattern}'`, { cwd, encoding: 'utf8' });
7069
return out.split('\n').filter(Boolean);
7170
}
7271

7372
// Run a given benchmark test with the provided revisions.
74-
function runBenchmark(benchmark, revisions) {
75-
const modules = revisions.map(revision =>
76-
require(path.join(
77-
dirForHash(hashForRevision(revision)),
78-
'dist',
79-
benchmark,
80-
)),
73+
function runBenchmark(benchmark, enviroments) {
74+
const modules = enviroments.map(({distPath}) =>
75+
require(path.join(distPath, benchmark)),
8176
);
8277
const suite = new Suite(modules[0].name, {
8378
onStart(event) {
@@ -94,28 +89,36 @@ function runBenchmark(benchmark, revisions) {
9489
beautifyBenchmark.log();
9590
},
9691
});
97-
for (let i = 0; i < revisions.length; i++) {
98-
suite.add(revisions[i], modules[i].measure);
92+
for (let i = 0; i < enviroments.length; i++) {
93+
suite.add(enviroments[i].revision, modules[i].measure);
9994
}
10095
suite.run({ async: false });
10196
}
10297

10398
// Prepare all revisions and run benchmarks matching a pattern against them.
10499
function prepareAndRunBenchmarks(benchmarkPatterns, revisions) {
105-
const benchmarks = findBenchmarks().filter(
106-
benchmark =>
107-
benchmarkPatterns.length === 0 ||
108-
benchmarkPatterns.some(pattern => benchmark.indexOf(pattern) !== -1),
109-
);
100+
// Find all benchmark tests to be run.
101+
let benchmarks = findFiles(LOCAL_DIR('src'), '*/__tests__/*-benchmark.js');
102+
if (benchmarkPatterns.length !== 0) {
103+
benchmarks = benchmarks.filter(
104+
benchmark => benchmarkPatterns.some(
105+
pattern => benchmark.indexOf(pattern) !== -1
106+
),
107+
);
108+
}
109+
110110
if (benchmarks.length === 0) {
111111
console.warn(
112112
'No benchmarks matching: ' +
113113
`\u001b[1m${benchmarkPatterns.join('\u001b[0m or \u001b[1m')}\u001b[0m`,
114114
);
115115
return;
116116
}
117-
revisions.forEach(revision => prepareRevision(revision));
118-
benchmarks.forEach(benchmark => runBenchmark(benchmark, revisions));
117+
118+
const enviroments = revisions.map(
119+
revision => ({ revision, distPath: prepareRevision(revision)})
120+
);
121+
benchmarks.forEach(benchmark => runBenchmark(benchmark, enviroments));
119122
}
120123

121124
function getArguments(argv) {

0 commit comments

Comments
 (0)