-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fs: buffer dir entries in opendir() #29893
Conversation
So this means that instead of 1 |
No, the API is unaffected and will still only return one item at a time.
Maybe? If you intentionally want a large number of directory entries at once you probably wouldn’t use the streaming API… |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty great work!
This is unlikely to be necessary in any case, and causes much unwarrented complexity when implementing further optimizations. Refs: nodejs#29893 (comment)
This is unlikely to be necessary in any case, and causes much unwarrented complexity when implementing further optimizations. Refs: #29893 (comment) PR-URL: #29908 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
Ok I landed #29908, lets see what this looks like without all that extra encoding nonsense. 😅 |
0ccb46c
to
4165094
Compare
@cjihrig @devnexen @Fishrock123 I’ve rebased this and it’s quite a bit simpler now, feel free to take another look |
Just thinking about it... given that e.g. const fs = require('fs');
let n = 0;
async function print(path) {
const dir = await fs.promises.opendir(path);
for await (const dirent of dir) {
fs.mkdirSync(`./foo${n++}`);
console.log(dirent.name);
}
}
print('./').catch(console.error); and const fs = require('fs');
const dir = fs.opendirSync(__dirname);
console.log(dir.readSync());
fs.mkdirSync('foo');
console.log(dir.readSync()); (the answer, of course, is that the newly created entries are not included in the iteration, but that should be documented :-) ...) |
This is unlikely to be necessary in any case, and causes much unwarrented complexity when implementing further optimizations. Refs: #29893 (comment) PR-URL: #29908 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Also if you could amend the commit to note that it it also includes misc cleanup that would be ideal)
@jasnell I believe that also applies to |
Read up to 32 directory entries in one batch when `dir.readSync()` or `dir.read()` are called. This increases performance significantly, although it introduces quite a bit of edge case complexity. confidence improvement accuracy (*) (**) (***) fs/bench-opendir.js mode='async' dir='lib' n=100 *** 155.93 % ±30.05% ±40.34% ±53.21% fs/bench-opendir.js mode='async' dir='test/parallel' n=100 *** 479.65 % ±56.81% ±76.47% ±101.32% fs/bench-opendir.js mode='sync' dir='lib' n=100 10.38 % ±14.39% ±19.16% ±24.96% fs/bench-opendir.js mode='sync' dir='test/parallel' n=100 *** 63.13 % ±12.84% ±17.18% ±22.58%
4165094
to
c66840d
Compare
That is not the answer, sorry – POSIX says:
I think it’s fair for our docs to reflect that, though. I’ve pushed c66840d for that.
(I assume the same goes for that, too.)
I’m not really seeing anything unrelated to the buffering, besides maybe removing the |
benchmark/fs/bench-opendir.js
Outdated
|
||
read(); | ||
}); | ||
} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@addaleax This patch seems wrong? There should be an else
here... I think the benchmark you ran included readSync()
along with the callback one...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, yes … funny the linter wouldn’t complain about this? The correct benchmark results for changing to setImmediate are
confidence improvement accuracy (*) (**) (***)
fs/bench-opendir.js mode='callback' dir='lib' n=100 3.40 % ±15.95% ±21.22% ±27.62%
fs/bench-opendir.js mode='callback' dir='test/parallel' n=100 *** -43.16 % ±10.70% ±14.27% ±18.66%
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This result seems strange to me, how is that worse than before?
Regardless though after further though I think that nextTick
is the reasonable thing to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Fishrock123 I think it makes sense – as you noted, the readSync()
part was run unconditionally before, so its (unchanged) performance was included in the -30 %. If we only benchmark what has been slowed down, seeing more negative impact seems about right to me.
c23f280
to
751a8b6
Compare
Read up to 32 directory entries in one batch when `dir.readSync()` or `dir.read()` are called. This increases performance significantly, although it introduces quite a bit of edge case complexity. confidence improvement accuracy (*) (**) (***) fs/bench-opendir.js mode='async' dir='lib' n=100 *** 155.93 % ±30.05% ±40.34% ±53.21% fs/bench-opendir.js mode='async' dir='test/parallel' n=100 *** 479.65 % ±56.81% ±76.47% ±101.32% fs/bench-opendir.js mode='sync' dir='lib' n=100 10.38 % ±14.39% ±19.16% ±24.96% fs/bench-opendir.js mode='sync' dir='test/parallel' n=100 *** 63.13 % ±12.84% ±17.18% ±22.58% PR-URL: #29893 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
PR-URL: #29893 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
Read up to 32 directory entries in one batch when `dir.readSync()` or `dir.read()` are called. This increases performance significantly, although it introduces quite a bit of edge case complexity. confidence improvement accuracy (*) (**) (***) fs/bench-opendir.js mode='async' dir='lib' n=100 *** 155.93 % ±30.05% ±40.34% ±53.21% fs/bench-opendir.js mode='async' dir='test/parallel' n=100 *** 479.65 % ±56.81% ±76.47% ±101.32% fs/bench-opendir.js mode='sync' dir='lib' n=100 10.38 % ±14.39% ±19.16% ±24.96% fs/bench-opendir.js mode='sync' dir='test/parallel' n=100 *** 63.13 % ±12.84% ±17.18% ±22.58% PR-URL: #29893 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
PR-URL: #29893 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
Read up to 32 directory entries in one batch when `dir.readSync()` or `dir.read()` are called. This increases performance significantly, although it introduces quite a bit of edge case complexity. confidence improvement accuracy (*) (**) (***) fs/bench-opendir.js mode='async' dir='lib' n=100 *** 155.93 % ±30.05% ±40.34% ±53.21% fs/bench-opendir.js mode='async' dir='test/parallel' n=100 *** 479.65 % ±56.81% ±76.47% ±101.32% fs/bench-opendir.js mode='sync' dir='lib' n=100 10.38 % ±14.39% ±19.16% ±24.96% fs/bench-opendir.js mode='sync' dir='test/parallel' n=100 *** 63.13 % ±12.84% ±17.18% ±22.58% PR-URL: #29893 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
PR-URL: #29893 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
Read up to 32 directory entries in one batch when
dir.readSync()
or
dir.read()
are called.This increases performance significantly, although it introduces
quite a bit of edge case complexity.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes