-
Testing
(comparing My Not sure if it's just rust or that they distribute the work over all cpu cores. Do you think using workers to distribute creating the file system entries could greatly boost cached installs? I'm sorry if I sound ridiculous as I'm aware that yarn solved this already with pnp mode. I just never switched, as it took too much time fighting the node ecosystem. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
It might very well be. For what it worth I have tried to rewrite tar unpacking in Zig and saw 2-3x time boost in install times for my side project: So, something is not very optimal with Node.js trying to write a bunch of files to the file system during install phase. It needs further investigation, exactly which operations in Node.js are inefficient and why. Perhaps just file writes? |
Beta Was this translation helpful? Give feedback.
-
We're using async I/O so they probably wouldn't, to quote the docs:
|
Beta Was this translation helpful? Give feedback.
-
Hm seem like your are right. If I bluntly inject myself by replacing all const realfs = require('node:fs')
const { performance } = require('node:perf_hooks');
const fs = {};
const nonMeasuredCalls = {};
const measuredCalls = {};
const measurementSum = {};
const lastCalls = [];
let ioActive = 0;
let maxIoActive = 0;
for (const name of Object.keys(realfs)) {
if (typeof realfs[name] !== 'function') {
fs[name] = realfs[name];
continue;
}
fs[name] = function() {
const args = Array.from(arguments);
const callback = args.at(-1);
const id = name;
lastCalls.length = 4;
lastCalls.unshift(id);
ioActive += 1;
maxIoActive = Math.max(ioActive, maxIoActive);
if (name.endsWith('Sync')) {
const start = performance.now();
const result = realfs[name].apply(this, arguments);
const end = performance.now();
measuredCalls[id] = (measuredCalls[id] ?? 0) + 1;
measurementSum[id] = (measurementSum[id] ?? 0) + end - start;
ioActive -= 1;
return result;
}
if (typeof callback === 'function') {
const start = performance.now();
return realfs[name].apply(this, args.concat(function() {
const end = performance.now();
measuredCalls[id] = (measuredCalls[id] ?? 0) + 1;
measurementSum[id] = (measurementSum[id] ?? 0) + end - start;
ioActive -= 1;
callback.apply(this, arguments);
}))
}
const result = realfs[name].apply(this, arguments);
nonMeasuredCalls[id] = (nonMeasuredCalls[id] ?? 0) + 1;
ioActive -= 1;
return result;
}
}
process.on('exit', () => {
console.log({nonMeasuredCalls, measuredCalls, measurementSum: Object.entries(measurementSum).map(([name, time]) => [name, time.toFixed(1) + 'ms']), lastCalls, maxIoActive})
})
module.exports = fs; Then the result is:
So yarn tries already to be as parallel as possible, but that darn |
Beta Was this translation helpful? Give feedback.
We're using async I/O so they probably wouldn't, to quote the docs: