Skip to content

Commit f34eb76

Browse files
committed
chore: more optimizations
1 parent 0261be7 commit f34eb76

File tree

5 files changed

+34
-51
lines changed

5 files changed

+34
-51
lines changed

bin/commands/generate.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const availableGenerators = Object.keys(publicGenerators);
1818

1919
// Half of available logical CPUs guarantees in general all physical CPUs are being used
2020
// which in most scenarios is the best way to maximize performance
21-
const optimalThreads = Math.floor(cpus().length / 2) - 1;
21+
const optimalThreads = Math.floor(cpus().length / 2) + 1;
2222

2323
/**
2424
* @typedef {Object} Options
@@ -79,7 +79,7 @@ export default {
7979
prompt: {
8080
type: 'text',
8181
message: 'Items per worker thread',
82-
initialValue: '20',
82+
initialValue: '10',
8383
},
8484
},
8585
version: {

src/generators.mjs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,40 +40,43 @@ const createGenerator = input => {
4040
const runGenerators = async options => {
4141
const { generators, threads } = options;
4242

43-
// WorkerPool for running full generators in worker threads
44-
const generatorPool = new WorkerPool('./generator-worker.mjs', threads);
45-
4643
// WorkerPool for chunk-level parallelization within generators
4744
const chunkPool = new WorkerPool('./chunk-worker.mjs', threads);
4845

49-
// Note that this method is blocking, and will only execute one generator per-time
50-
// but it ensures all dependencies are resolved, and that multiple bottom-level generators
51-
// can reuse the already parsed content from the top-level/dependency generators
46+
// Schedule all generators, allowing independent ones to run in parallel.
47+
// Each generator awaits its own dependency internally, so generators
48+
// with the same dependency (e.g. legacy-html and legacy-json both depend
49+
// on metadata) will run concurrently once metadata resolves.
5250
for (const generatorName of generators) {
51+
// Skip if already scheduled
52+
if (generatorName in cachedGenerators) {
53+
continue;
54+
}
55+
5356
const { dependsOn, generate } = allGenerators[generatorName];
5457

55-
// If the generator dependency has not yet been resolved, we resolve
56-
// the dependency first before running the current generator
57-
if (dependsOn && dependsOn in cachedGenerators === false) {
58+
// Ensure dependency is scheduled (but don't await its result yet)
59+
if (dependsOn && !(dependsOn in cachedGenerators)) {
5860
await runGenerators({ ...options, generators: [dependsOn] });
5961
}
6062

61-
// Ensures that the dependency output gets resolved before we run the current
62-
// generator with its dependency output as the input
63-
const input = await cachedGenerators[dependsOn];
64-
65-
// Create a ParallelWorker for this generator to use for item-level parallelization
63+
// Create a ParallelWorker for this generator
6664
const worker = createParallelWorker(generatorName, chunkPool, options);
6765

68-
// Adds the current generator execution Promise to the cache
69-
cachedGenerators[generatorName] =
70-
threads < 2
71-
? generate(input, { ...options, worker })
72-
: generatorPool.run({ generatorName, input, options });
66+
/**
67+
* Schedule the generator - it awaits its dependency internally
68+
* his allows multiple generators with the same dependency to run in parallel
69+
*/
70+
const scheduledGenerator = async () => {
71+
const input = await cachedGenerators[dependsOn];
72+
73+
return generate(input, { ...options, worker });
74+
};
75+
76+
cachedGenerators[generatorName] = scheduledGenerator();
7377
}
7478

7579
// Returns the value of the last generator of the current pipeline
76-
// Note that dependencies will be awaited (as shown on line 48)
7780
return cachedGenerators[generators[generators.length - 1]];
7881
};
7982

src/generators/ast-js/index.mjs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@ export default {
3030
*/
3131
async processChunk(_, itemIndices, { input }) {
3232
const { loadFiles } = createJsLoader();
33-
const sourceFiles = loadFiles(input ?? []);
34-
3533
const { parseJsSource } = createJsParser();
3634

3735
const results = [];
3836

3937
for (const idx of itemIndices) {
40-
results.push(await parseJsSource(sourceFiles[idx]));
38+
const [file] = loadFiles(input[idx]);
39+
40+
const parsedFile = await parseJsSource(file);
41+
42+
results.push(parsedFile);
4143
}
4244

4345
return results;
@@ -48,12 +50,11 @@ export default {
4850
* @param {Partial<GeneratorOptions>} options
4951
*/
5052
async generate(_, { input, worker }) {
51-
const { loadFiles } = createJsLoader();
52-
5353
// Load all of the Javascript sources into memory
54-
const sourceFiles = loadFiles(input ?? []);
54+
const sourceFiles =
55+
input?.filter(filename => filename.endsWith('.js')) ?? [];
5556

5657
// Parse the Javascript sources into ASTs in parallel using worker threads
57-
return worker.map(sourceFiles, _, { input });
58+
return worker.map(sourceFiles, _, { input: sourceFiles });
5859
},
5960
};

src/parsers/javascript.mjs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ const createParser = () => {
2929
locations: true,
3030
});
3131

32-
return {
33-
...res,
34-
path: resolvedSourceFile.path,
35-
};
32+
return { ...res, path: resolvedSourceFile.path };
3633
};
3734

3835
/**

src/threading/generator-worker.mjs

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)