-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
Description
This topic already been discussed before in the following issues/PRs:
- Runtime information about libc version and typeΒ #39877
- src: add glibcCompiler and glibcRuntime to process.versionsΒ #41338
While this was considered a resolved topic as we can get the information from process.report.getReport
, I want to put more focus on the performance implications of not exposing this information.
Current Performance
Below, is the op/s to check if the system is musl
using many methods I saw using this code search:
process.report.getReport() x 218 ops/sec Β±4.16% (76 runs sampled)
isMusl x 167 ops/sec Β±1.94% (74 runs sampled)
isMuslByFile x 95,904 ops/sec Β±2.67% (80 runs sampled)
Fastest is isMuslByFile
benchmark.js
const Benchmark = require('benchmark');
const suite = new Benchmark.Suite();
const decoder = new TextDecoder();
const isMusl = () => {
try {
const lddPath = decoder.decode(require('child_process').execSync('ldd --version')).includes('musl')
return lddPath
} catch (e) {
return true
};
}
function isMuslByFile() {
try {
return readFileSync('/usr/bin/ldd', 'utf8').includes('musl')
} catch (e) {
return true
}
}
suite.add('process.report.getReport()', function () {
const id = !process.report.getReport().header.glibcVersionRuntime;
});
suite.add(`isMusl`, function () {
const result = isMusl();
});
suite.add(`isMuslByFile`, function () {
const result = isMuslByFile();
});
suite
// add listeners
.on('cycle', function (event) {
console.log(String(event.target));
})
.on('complete', function () {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.run({
async: true,
});
Above, is just the time spent in a benchmark, in real life, v8 will not optimize this function soo much, below the profile of swcx (rust binding for swc
).
Command: node --cpu-prof swcx/index.js
Profile: swcx.cpuprofile.zip
Implications
These libraries usually implement their own version instead of installing a library like detect-libc to have a standardized way to check if the system is musl
. This means that almost every nodejs
package that checks if it is musl
will increase the startup time by some range of 5~30ms.
But even using detect-libc
, it didn't cache the result value if the system is musl
, so the problem with initialization is also a problem here, and this library is downloaded 9 million times, which means a lot of time can be saved here.
Actually, detect-libc
caches the value after the first run, so if multiple libraries use this lib to check for musl
, they can benefit from this cache.
This issue can also affect NPM
or any package manager if they decide to follow this RFC: npm/rfcs#519 if they decide to provide support for npm/rfcs#519 (comment). With this implementation, possibly every x64 linux will have some startup penalty but at least this will only be once, as the library no longer needs to do this check.
Conclusion
There is a lot of time that can be saved by just exposing that information directly instead of relying on process.report.getReport
. The main benefit will be for many libraries that expose native bindings with NodeJS.
So, I want to raise some feedback about this, especially from @styfle, @Brooooooklyn, @richardlau and @bnoordhuis.