Skip to content

Commit 55eff4b

Browse files
AlpAlp
authored andcommitted
test: add actual benchmark comparing eager vs targeted file loading
The benchmark test now measures both approaches with timing: - Eager: loads all files from all tsconfigs (500+ files) - Targeted: loads only the requested config file (1 file) - Comparison test asserts targeted is faster and loads fewer files
1 parent 0196312 commit 55eff4b

File tree

1 file changed

+72
-14
lines changed

1 file changed

+72
-14
lines changed

tests/benchmark.test.ts

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import * as path from 'node:path';
22
import {Project} from 'ts-morph';
3-
import {test, expect} from 'vitest';
4-
import {ensureSourceFileInProject} from '../src/cli/ts-project';
3+
import {describe, test, expect} from 'vitest';
4+
import {addSourceFilesFromTsConfigSafe, ensureSourceFileInProject} from '../src/cli/ts-project';
5+
import {discoverAllTsConfigs} from '../src/cli/tsconfig';
56

67
const fixtureRoot = path.resolve(
78
__dirname,
@@ -12,28 +13,85 @@ const schemaConfigFile = path.resolve(
1213
'benchmarks/synthetic-monorepo/schema/drizzle-zero.config.ts',
1314
);
1415

15-
test(
16-
'project only loads the explicitly added file, not all tsconfig files',
17-
{timeout: 120_000},
18-
async () => {
16+
describe('file loading performance', {timeout: 120_000}, () => {
17+
test('eager loading pulls in all files from all tsconfigs', async () => {
18+
const start = performance.now();
19+
20+
const allTsConfigPaths = await discoverAllTsConfigs(fixtureRoot);
1921
const project = new Project({
2022
tsConfigFilePath: fixtureRoot,
2123
skipAddingFilesFromTsConfig: true,
2224
});
25+
for (const tsConfigPath of allTsConfigPaths) {
26+
addSourceFilesFromTsConfigSafe({tsProject: project, tsConfigPath});
27+
}
28+
29+
const eagerTime = performance.now() - start;
30+
const eagerFileCount = project.getSourceFiles().length;
31+
32+
console.log(`Eager: ${eagerFileCount} files in ${eagerTime.toFixed(1)}ms`);
33+
34+
// Eager should load all fixture files (500+)
35+
expect(eagerFileCount).toBeGreaterThan(400);
36+
});
2337

38+
test('targeted loading only loads the requested file', async () => {
39+
const start = performance.now();
40+
41+
const project = new Project({
42+
tsConfigFilePath: fixtureRoot,
43+
skipAddingFilesFromTsConfig: true,
44+
});
2445
ensureSourceFileInProject({
2546
tsProject: project,
2647
filePath: schemaConfigFile,
2748
debug: false,
2849
});
2950

30-
const fileCount = project.getSourceFiles().length;
51+
const lazyTime = performance.now() - start;
52+
const lazyFileCount = project.getSourceFiles().length;
3153

32-
console.log(`Files loaded: ${fileCount}`);
54+
console.log(`Targeted: ${lazyFileCount} files in ${lazyTime.toFixed(1)}ms`);
3355

34-
// Regression guard: only the config file (and possibly a few resolved
35-
// dependencies) should be loaded. If someone accidentally re-introduces
36-
// eager loading, this will catch it.
37-
expect(fileCount).toBeLessThan(10);
38-
},
39-
);
56+
// Only the config file should be loaded
57+
expect(lazyFileCount).toBeLessThan(10);
58+
});
59+
60+
test('targeted loading is faster than eager loading', async () => {
61+
// Eager
62+
const eagerStart = performance.now();
63+
const allTsConfigPaths = await discoverAllTsConfigs(fixtureRoot);
64+
const eagerProject = new Project({
65+
tsConfigFilePath: fixtureRoot,
66+
skipAddingFilesFromTsConfig: true,
67+
});
68+
for (const tsConfigPath of allTsConfigPaths) {
69+
addSourceFilesFromTsConfigSafe({tsProject: eagerProject, tsConfigPath});
70+
}
71+
const eagerTime = performance.now() - eagerStart;
72+
const eagerFileCount = eagerProject.getSourceFiles().length;
73+
74+
// Targeted (current default)
75+
const lazyStart = performance.now();
76+
const lazyProject = new Project({
77+
tsConfigFilePath: fixtureRoot,
78+
skipAddingFilesFromTsConfig: true,
79+
});
80+
ensureSourceFileInProject({
81+
tsProject: lazyProject,
82+
filePath: schemaConfigFile,
83+
debug: false,
84+
});
85+
const lazyTime = performance.now() - lazyStart;
86+
const lazyFileCount = lazyProject.getSourceFiles().length;
87+
88+
const speedup = eagerTime / lazyTime;
89+
90+
console.log(`Eager: ${eagerFileCount} files in ${eagerTime.toFixed(1)}ms`);
91+
console.log(`Targeted: ${lazyFileCount} files in ${lazyTime.toFixed(1)}ms`);
92+
console.log(`Speedup: ${speedup.toFixed(1)}x faster`);
93+
94+
expect(lazyFileCount).toBeLessThan(eagerFileCount);
95+
expect(lazyTime).toBeLessThan(eagerTime);
96+
});
97+
});

0 commit comments

Comments
 (0)