Performance of node:fs #106
Copy link
Copy link
Open
nodejs/node
#49593Description
node:fs is based on FSReqCallback and makes multiple C++ calls for any operation. There are lots of places where we could just open, stat and perform the operation using only 1 C++ call.
An example PR that provided performance boost was: nodejs/node#48658.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
anonrig commentedon Sep 17, 2023
Sync methods
chmod+fchmodnode#49859chownSyncnode#49748chmod+fchmodnode#49859fdatasyncSyncnode#49898lstat+fstatnode#49868fsyncSyncnode#49880ftruncateSyncnode#50032*timesnode#49864node:fserror path performance improvements node#49962*timesnode#49864node:fserror path performance improvements node#49962lstat+fstatnode#49868mkdirSyncnode#49847fs.mkdtempSyncnode#49750opendirSyncnode#49705readdirSyncnode#50131readFileSyncwith file descriptors node#49691node:fserror path performance improvements node#49962readSyncnode#50033readSyncnode#50033fs.renameSyncnode#49863rmdirSyncnode#49846node:fserror path performance improvements node#49962ftruncateSyncnode#50032unlinkSyncnode#49856*timesnode#49864tony-go commentedon Sep 19, 2023
It's definitely a good idea to tackle syncs as we don't have to handle callbacks in c++ land as with async methods.
fs: improve error performance of `opendirSync`
CanadaHonk commentedon Sep 26, 2023
Would
rimraflikely benefit from being rewritten in C++ rather than in JS using FS APIs? Potential issue/idea for the future.CanadaHonk commentedon Sep 26, 2023
Encoding C++ fast paths
utf8readFileSyncfs: add a fast-path for readFileSync utf-8 node#48658writeFileSyncfs: add c++ fast path for writeFileSync string utf8 node#49884ascii/latin1ascii/latin1allows using one byte V8 strings in/out which can save string copies and potentially lead to some speedups (needs investigation).See also: nodejs/node#49888
benjamingr commentedon Sep 27, 2023
readfile intentionally splits the file into many reads to avoid contention but that could could live in C++ and readFile would could be a single JS->CPP call (and one CPP->JS for the callback)
CanadaHonk commentedon Sep 27, 2023
^ fwiw this only happens in current non-fast path atm (non-utf8 encoding)
Uzlopak commentedon Sep 27, 2023
Should we maybe put in the docs, that using a number instead of a string for
modeis significantly faster?nodejs/node#49756 (comment)
Uzlopak commentedon Sep 27, 2023
My benchmarks show that using a string for mode is about 12 Million ops/s and a number about 250 Million ops/s. My suggestion for string in the above comment makes it about 80 Million ops/s for but is still slower than simply to use a number.
CanadaHonk commentedon Sep 27, 2023
It could also be interesting to make a Node option/something which would log/warn when missing potential faster internal/FS paths (eg
readFileSyncutf8 encoding, or using a string as a mode, ...)aduh95 commentedon Sep 27, 2023
My two cents on this: we should avoid putting performance recommendation in there as it's likely to get outdated without us noticing. We could update the examples to use a constant if they are not already, so it nudges the reader to use the (currently) faster alternative.
CanadaHonk commentedon Sep 27, 2023
Related a bit, I noticed we use strings as default flag for some common FS ops, it might be a bit faster to use numbers instead?
Uzlopak commentedon Sep 27, 2023
There are two params. flag and mode. I just found
test-fs-existssync-false.jswhere we use '0777' instead of 0o777. This could be changed to avoid the conversion bottleneck.What do you refer to?
94 remaining items
fs: improve error performance of readvSync
fs: throw fchownSync error from c++
fs: improve error performance for `rmdirSync`
fs: improve error perf of sync `lstat`+`fstat`
fs: improve error performance for `rmdirSync`
fs: improve error perf of sync `lstat`+`fstat`
fs: improve error perf of sync `lstat`+`fstat`
fs: improve error performance of readvSync
fs: throw fchownSync error from c++
fs: improve error performance for `unlinkSync`
fs: improve error performance for `fdatasyncSync`
fs: improve error performance for `ftruncateSync`
fs: improve error performance of writevSync