Skip to content

Commit 7eb199f

Browse files
committed
Benchmark: replace shell scripts with JS code
1 parent f68e8e2 commit 7eb199f

File tree

1 file changed

+56
-53
lines changed

1 file changed

+56
-53
lines changed

resources/benchmark.js

+56-53
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,55 +32,48 @@ 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-
cp -R "${LOCAL_DIR}/src/__fixtures__" "${dir}/src/__fixtures__" &&
60-
(cd "${dir}" && yarn run ${BUILD_CMD})
61-
`);
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(`cp -R "${LOCAL_DIR()}/src/__fixtures__/" "${dir}/src/__fixtures__/"`);
62+
execSync(`yarn run ${BUILD_CMD}`, { cwd: dir });
63+
64+
return path.join(dir, 'dist');
6265
}
6366
}
6467

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

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

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

122125
function getArguments(argv) {

0 commit comments

Comments
 (0)