Skip to content

Commit 136c57a

Browse files
committed
fixup! test(@angular/build): add library builder scaling benchmark suite
1 parent 19f942c commit 136c57a

2 files changed

Lines changed: 69 additions & 39 deletions

File tree

‎scripts/benchmark.mts‎

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function checkBuildStatus(logger: Console): boolean {
3232
if (srcMtime > distMtime) {
3333
logger.warn(
3434
'Warning: Source files in packages/angular/build are newer than dist/.\n' +
35-
'Run "pnpm build" to ensure your benchmark reflects your latest local edits.\n',
35+
'Run "pnpm build" to ensure your benchmark reflects your latest local edits.\n',
3636
);
3737
}
3838
}
@@ -54,7 +54,7 @@ async function runLibraryBuilderSubsystem(options: {
5454
}): Promise<number> {
5555
if (options.layout !== undefined && options.layout !== 'flat' && options.layout !== 'deep') {
5656
// eslint-disable-next-line no-console
57-
console.error(`Error: --layout must be "flat" or "deep", got "${options.layout}".`);
57+
console.error("Error: --layout must be \"flat\" or \"deep\", got \"" + options.layout + "\".");
5858

5959
return 1;
6060
}
@@ -64,18 +64,42 @@ async function runLibraryBuilderSubsystem(options: {
6464
) {
6565
// eslint-disable-next-line no-console
6666
console.error(
67-
`Error: --style must be one of "inline", "inline-scss", "external", got "${options.style}".`,
67+
"Error: --style must be one of \"inline\", \"inline-scss\", \"external\", got \"" + options.style + "\"."
6868
);
6969

7070
return 1;
7171
}
7272

73+
const sizes = parseIntList(options.sizes);
74+
if (sizes !== undefined && sizes.some((n) => !Number.isInteger(n) || n < 1)) {
75+
// eslint-disable-next-line no-console
76+
console.error("Error: --sizes must be a comma-separated list of positive integers, got \"" + options.sizes + "\".");
77+
78+
return 1;
79+
}
80+
81+
const depths = parseIntList(options.depths);
82+
if (depths !== undefined && depths.some((n) => !Number.isInteger(n) || n < 1)) {
83+
// eslint-disable-next-line no-console
84+
console.error("Error: --depths must be a comma-separated list of positive integers, got \"" + options.depths + "\".");
85+
86+
return 1;
87+
}
88+
89+
const iterations = options.iterations !== undefined ? Number(options.iterations) : undefined;
90+
if (iterations !== undefined && (!Number.isInteger(iterations) || iterations < 1)) {
91+
// eslint-disable-next-line no-console
92+
console.error("Error: --iterations must be a positive integer, got \"" + options.iterations + "\".");
93+
94+
return 1;
95+
}
96+
7397
const cliOptions: LibraryBuilderBenchmarkOptions = {
7498
layout: options.layout as LibraryBuilderBenchmarkOptions['layout'],
7599
style: options.style as LibraryBuilderBenchmarkOptions['style'],
76-
sizes: parseIntList(options.sizes),
77-
depths: parseIntList(options.depths),
78-
iterations: options.iterations !== undefined ? Number(options.iterations) : undefined,
100+
sizes,
101+
depths,
102+
iterations,
79103
json: Boolean(options.json),
80104
};
81105

‎scripts/benchmarks/library-builder/index.mts‎

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function checkBuilderIsBuilt(
5858
if (!fs.existsSync(path.join(buildPkg, 'package.json')) || !fs.existsSync(architectCli)) {
5959
logger.error(
6060
'Error: @angular/build and/or @angular-devkit/architect have not been built yet.\n' +
61-
'Run "pnpm build" (or "pnpm admin build --local" for a faster local build) first.',
61+
'Run "pnpm build" (or "pnpm admin build --local" for a faster local build) first.',
6262
);
6363

6464
return undefined;
@@ -171,6 +171,10 @@ function buildOnce(
171171
const durationMs = performance.now() - start;
172172
const status = result.status === 0 ? 'ok' : 'fail';
173173
if (status === 'fail') {
174+
if (result.error) {
175+
// eslint-disable-next-line no-console
176+
console.error(result.error);
177+
}
174178
// eslint-disable-next-line no-console
175179
console.error(result.stdout?.toString());
176180
// eslint-disable-next-line no-console
@@ -207,49 +211,51 @@ export async function runLibraryBuilderBenchmarks(
207211
fs.mkdirSync(scratchRoot, { recursive: true });
208212
const measurements: BuildMeasurement[] = [];
209213

210-
for (const sizeOrDepth of sizes) {
211-
const label = `${layout}-${style}-${layout === 'deep' ? `depth${sizeOrDepth}` : sizeOrDepth}`;
212-
const projectDir = path.join(scratchRoot, label);
213-
214-
const fixtureOptions: FixtureOptions =
215-
layout === 'flat'
216-
? { layout, style, count: sizeOrDepth }
217-
: { layout, style, depth: sizeOrDepth };
218-
const entryPoints = generateFixture(projectDir, fixtureOptions);
214+
try {
215+
for (const sizeOrDepth of sizes) {
216+
const label = layout + "-" + style + "-" + (layout === "deep" ? "depth" + sizeOrDepth : sizeOrDepth);
217+
const projectDir = path.join(scratchRoot, label);
219218

220-
if (!options.json) {
221-
// eslint-disable-next-line no-console
222-
console.log(`\n[library-builder] ${label} (${entryPoints} entry points)`);
223-
}
219+
const fixtureOptions: FixtureOptions =
220+
layout === 'flat'
221+
? { layout, style, count: sizeOrDepth }
222+
: { layout, style, depth: sizeOrDepth };
223+
const entryPoints = generateFixture(projectDir, fixtureOptions);
224224

225-
const durations: number[] = [];
226-
for (let i = 1; i <= iterations; i++) {
227-
const { durationMs, status } = buildOnce(projectDir, builder.architectCli);
228225
if (!options.json) {
226+
// eslint-disable-next-line no-console
227+
console.log("\n[library-builder] " + label + " (" + entryPoints + " entry points)");
228+
}
229+
230+
const durations: number[] = [];
231+
for (let i = 1; i <= iterations; i++) {
232+
const { durationMs, status } = buildOnce(projectDir, builder.architectCli);
233+
if (!options.json) {
234+
// eslint-disable-next-line no-console
235+
console.log(
236+
" run " + i + "/" + iterations + ": " + (status === 'ok' ? 'done' : 'FAILED') + " in " + (durationMs / 1000).toFixed(2) + "s"
237+
);
238+
}
239+
if (status === 'ok') {
240+
durations.push(durationMs);
241+
}
242+
measurements.push({ layout, style, entryPoints, iteration: i, durationMs, status });
243+
}
244+
245+
if (!options.json && durations.length > 0) {
246+
const medianMs = median(durations);
229247
// eslint-disable-next-line no-console
230248
console.log(
231-
` run ${i}/${iterations}: ${status === 'ok' ? 'done' : 'FAILED'} in ${(durationMs / 1000).toFixed(2)}s`,
249+
" median: " + (medianMs / 1000).toFixed(2) + "s (" + (medianMs / entryPoints).toFixed(2) + "ms/entry)"
232250
);
233251
}
234-
if (status === 'ok') {
235-
durations.push(durationMs);
236-
}
237-
measurements.push({ layout, style, entryPoints, iteration: i, durationMs, status });
238-
}
239252

240-
if (!options.json && durations.length > 0) {
241-
const medianMs = median(durations);
242-
// eslint-disable-next-line no-console
243-
console.log(
244-
` median: ${(medianMs / 1000).toFixed(2)}s (${(medianMs / entryPoints).toFixed(2)}ms/entry)`,
245-
);
253+
fs.rmSync(projectDir, { recursive: true, force: true });
246254
}
247-
248-
fs.rmSync(projectDir, { recursive: true, force: true });
255+
} finally {
256+
fs.rmSync(scratchRoot, { recursive: true, force: true });
249257
}
250258

251-
fs.rmSync(scratchRoot, { recursive: true, force: true });
252-
253259
const anyFailed = measurements.some((m) => m.status === 'fail');
254260
if (options.json) {
255261
// eslint-disable-next-line no-console

0 commit comments

Comments
 (0)