|
1 | | -import type { CacheConfig, ResultIdentifier } from "./config"; |
| 1 | +import type { CacheConfig, WorkerResult, SuiteRawResult } from "./types"; |
2 | 2 |
|
3 | | -import { CACHE_FACTORIES } from "./config"; |
4 | 3 | import fs from "fs"; |
5 | | -import { isResultReliable, groupResults, getSummary } from "./reliability"; |
| 4 | +import path from "path"; |
| 5 | +import { CACHE_FACTORIES } from "./config"; |
| 6 | +import { getSummary } from "./reliability/reliability"; |
6 | 7 | import { log } from "./utils/logger"; |
7 | 8 | import { analyzeResults } from "./analyze-results"; |
8 | 9 | import { CONFIG } from "./config"; |
9 | | -import { scenarios } from "./scenarios"; |
10 | 10 | import { spawn } from "child_process"; |
11 | | -import path from "path"; |
| 11 | +import { mergeResults } from "./utils/merge"; |
| 12 | +import { isReliable } from "./utils/reliability"; |
12 | 13 |
|
13 | | -export interface Result extends ResultIdentifier { |
14 | | - scenario: `${(typeof scenarios)[number]["name"]}_${number}`; |
15 | | - samples: number[]; |
16 | | - operationName: string; |
17 | | -} |
18 | | - |
19 | | -interface BenchmarkJob { |
| 14 | +interface BaseSuite { |
20 | 15 | cacheFactory: (typeof CACHE_FACTORIES)[number]; |
21 | 16 | cacheConfig: CacheConfig; |
22 | 17 | } |
23 | 18 |
|
24 | | -const benchmarkJobs: BenchmarkJob[] = []; |
| 19 | +const BASE_SUITES: BaseSuite[] = []; |
| 20 | + |
25 | 21 | for (const cacheFactory of CACHE_FACTORIES) { |
26 | 22 | for (const cacheConfig of CONFIG.cacheConfigurations) { |
27 | | - benchmarkJobs.push({ cacheFactory, cacheConfig }); |
| 23 | + BASE_SUITES.push({ cacheFactory, cacheConfig }); |
28 | 24 | } |
29 | 25 | } |
30 | 26 |
|
31 | | -function runBenchmarkInIsolatedProcess(job: BenchmarkJob): Promise<Result[]> { |
| 27 | +const spawnProcess = (job: BaseSuite): Promise<WorkerResult> => { |
32 | 28 | return new Promise((resolve) => { |
33 | | - const workerScript = path.join( |
34 | | - __dirname, |
35 | | - "..", |
36 | | - "lib", |
37 | | - "benchmark-worker.js", |
38 | | - ); |
39 | | - const child = spawn(process.execPath, [workerScript, JSON.stringify(job)], { |
40 | | - env: { |
41 | | - ...process.env, |
| 29 | + const workerScript = path.join(__dirname, "..", "lib", "suite-worker.js"); |
| 30 | + const child = spawn( |
| 31 | + process.execPath, |
| 32 | + [ |
| 33 | + "--max-old-space-size=1000", |
| 34 | + "--max-semi-space-size=512", |
| 35 | + "--noconcurrent_sweeping", |
| 36 | + workerScript, |
| 37 | + JSON.stringify(job), |
| 38 | + ], |
| 39 | + { |
| 40 | + env: { |
| 41 | + ...process.env, |
| 42 | + }, |
| 43 | + stdio: ["pipe", "pipe"], |
42 | 44 | }, |
43 | | - stdio: ["pipe", "pipe", "pipe"], |
44 | | - }); |
| 45 | + ); |
45 | 46 |
|
46 | 47 | let stdout = ""; |
47 | 48 |
|
48 | 49 | child.stdout.on("data", (data) => { |
49 | 50 | stdout += data.toString(); |
50 | 51 | }); |
51 | 52 |
|
52 | | - child.stderr.on("data", (data) => { |
53 | | - console.error(`Worker stderr: ${data}`); |
54 | | - }); |
55 | | - |
56 | 53 | child.on("close", () => { |
57 | 54 | const results = JSON.parse(stdout.trim()); |
58 | 55 | resolve(results); |
59 | 56 | }); |
60 | 57 | }); |
61 | | -} |
| 58 | +}; |
62 | 59 |
|
63 | | -async function runBenchmarkSuite(): Promise<Result[]> { |
64 | | - const allResults: Result[] = []; |
| 60 | +const runBaseSuites = async (): Promise<WorkerResult[]> => { |
| 61 | + const allResults: WorkerResult[] = []; |
65 | 62 |
|
66 | | - for (const job of benchmarkJobs) { |
| 63 | + for (const suite of BASE_SUITES) { |
67 | 64 | console.log( |
68 | | - `\n=== Running benchmarks for ${job.cacheFactory.name} with ${job.cacheConfig.name} in isolated process ===`, |
| 65 | + `\n=== Running benchmarks for ${suite.cacheFactory.name} with ${suite.cacheConfig.name} in isolated process ===`, |
69 | 66 | ); |
70 | 67 |
|
71 | | - const jobResults = await runBenchmarkInIsolatedProcess(job); |
72 | | - allResults.push(...jobResults); |
| 68 | + const result = await spawnProcess(suite); |
| 69 | + allResults.push(result); |
73 | 70 | console.log( |
74 | | - `Completed ${job.cacheFactory.name}/${job.cacheConfig.name} with ${jobResults.length} results`, |
| 71 | + `Completed ${suite.cacheFactory.name}/${suite.cacheConfig.name} with ${result.results.length} results`, |
75 | 72 | ); |
76 | 73 | } |
77 | 74 |
|
78 | 75 | return allResults; |
79 | | -} |
80 | | - |
81 | | -export interface BenchmarkResult { |
82 | | - [scenarioName: string]: Result[]; |
83 | | -} |
| 76 | +}; |
84 | 77 |
|
85 | | -async function runBenchmarks(): Promise<void> { |
| 78 | +const runBenchmarks = async (): Promise<void> => { |
86 | 79 | const { maxAttempts } = CONFIG.reliability; |
87 | | - let prevBenchmarks: BenchmarkResult[] = []; |
| 80 | + let prevSuites: SuiteRawResult[] = []; |
88 | 81 | log.start(); |
89 | 82 | for (let attempt = 1; attempt <= maxAttempts; attempt++) { |
90 | 83 | log.attempt(attempt); |
91 | 84 |
|
92 | | - const currentResult = await runBenchmarkSuite(); |
93 | | - const groupedResults = groupResults(currentResult); |
94 | | - const isReliable = isResultReliable(groupedResults, prevBenchmarks); |
| 85 | + const results = await runBaseSuites(); |
| 86 | + const groupedResult = mergeResults(results); |
| 87 | + const isSuiteReliable = isReliable(groupedResult, prevSuites); |
95 | 88 |
|
96 | | - prevBenchmarks.push(groupedResults); |
| 89 | + prevSuites.push(groupedResult); |
97 | 90 |
|
98 | | - if (isReliable && attempt > CONFIG.reliability.minAttempts) { |
| 91 | + if (isSuiteReliable && attempt > CONFIG.reliability.minAttempts) { |
99 | 92 | break; |
100 | 93 | } |
101 | 94 | } |
102 | 95 |
|
103 | | - const summary = getSummary(prevBenchmarks); |
104 | | - analyzeResults(summary); |
| 96 | + const summary = getSummary(prevSuites); |
| 97 | + const report = analyzeResults(summary); |
105 | 98 | fs.writeFileSync("benchmark-summary.json", JSON.stringify(summary, null, 2)); |
106 | | -} |
| 99 | + fs.writeFileSync( |
| 100 | + "benchmark-summary-report.json", |
| 101 | + JSON.stringify(report, null, 2), |
| 102 | + ); |
| 103 | +}; |
107 | 104 |
|
108 | 105 | runBenchmarks(); |
0 commit comments