Conversation
Worker stdio loads stream after restoring the main-thread context, initializing its constructors and prototype methods on every startup. Preload stream during snapshot construction so workers can restore that initialized state instead. Worker-specific stdio instances and message ports are still created at runtime. Add a concurrent startup benchmark and verify snapshot membership, stdio methods, and isolation from parent-thread stream mutations. Assisted-by: pi Signed-off-by: Matteo Collina <hello@matteocollina.com>
|
Review requested:
|
Keep Readable and Writable eagerly initialized for worker stdio, but load operators, pipeline, compose, promises, and the other stream constructors on demand. This keeps their implementation state out of the startup snapshot when it is not needed. Preserve export identity, prototype descriptors, and promisification. Install subclass methods before linking prototype chains so lazy loading also works when a base constructor or prototype has been frozen. Update the bootstrap inventory and add lazy-loading compatibility tests. Assisted-by: pi Signed-off-by: Matteo Collina <hello@matteocollina.com>
|
Added lazy stream initialization in 1a9691a. Readable and Writable remain eagerly initialized for worker stdio; operators, pipeline, compose, promises, and the other stream constructors load on demand. Compared the combined changes at 1a9691a against the original baseline, 4889fb0, on an Intel i7-7700 (4 cores / 8 hardware threads), using release builds with identical configuration. Percentages are changes in mean throughput; positive means faster. For
This measures time until all workers are online, keeping workers alive until then so teardown does not compete with startup. The ± values are the harness's unadjusted 95% accuracy estimates. All four gains survive Holm correction at 5%, in both orders. Full-lifecycle results from
Empty and immediate-stream-use cases used 60 samples per binary/mode, with 30 starts per sample. Builtin-loading cases used 40 samples with 10 starts per sample. All differences except empty CommonJS process startup survive Holm correction across the 14 primary comparisons, including the worker-online cases. There is a small regression for empty ESM processes: about 0.45 ms per lifecycle. A separate 100-sample run with reversed binary order reproduced it at −1.49%. The measured builtin-loading and stream-use workloads improved, but these results do not establish a universal no-regression claim. The immediate-stream-use fixture was: 'use strict';
const { Readable, Writable, pipeline } = require('node:stream');
pipeline(
Readable.from([1, 2, 3]).map((value) => value * 2),
new Writable({ objectMode: true, write(value, encoding, callback) { callback(); } }),
(error) => { if (error) throw error; },
);Worker-online comparison command, with binaries built at the two commits: ./node benchmark/compare.js --old /path/to/baseline --new /path/to/candidate \
--runs 100 --filter startup --no-progress --analyze worker |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #66311 +/- ##
==========================================
- Coverage 90.37% 90.36% -0.02%
==========================================
Files 790 792 +2
Lines 274497 275599 +1102
Branches 52562 52830 +268
==========================================
+ Hits 248077 249040 +963
- Misses 16921 16987 +66
- Partials 9499 9572 +73
🚀 New features to boost your workflow:
|
Allow defineLazyProperties to map property names directly to module IDs so stream can expose function exports without a separate lazy module. Keep only module IDs in native callback data for snapshot serialization. Set the mapping object's prototype to null after creation to retain fast properties without inheriting from Object.prototype. Assisted-by: pi Signed-off-by: Matteo Collina <hello@matteocollina.com>
Worker stdio loads stream after restoring the main-thread context, initializing its constructors and prototype methods on every startup. Preload stream during snapshot construction so workers can restore that initialized state instead. Worker-specific stdio instances and message ports are still created at runtime.
Add a concurrent startup benchmark and verify snapshot membership, stdio methods, and isolation from parent-thread stream mutations.
AI generated, reviewed by me.