Some improvements to readdir, readdir_n #292
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This eliminates the unnecessary allocations in
readdir_n
mentioned in #290. It also fixes several bugs, including buffer overflows.With a slightly expanded version of the reproduction case from #290, the timings on my machine are
So there is some performance improvement, but more would be better. I will look into what else can be done, for a separate potential PR.
It occurs to me that
readdir_n
andfiles_of_directory
shouldn't be in the interface at all, however.The underlying C library's
readdir_r
internally retrieves multiple directory entries by system call, and stores them in a buffer. Subsequent calls toreaddir_r
just read this buffer until it is drained.However, Lwt always runs
readdir_r
in separate worker threads, because Lwt does not know whenreaddir_r
will only read the buffer, and when it will run a potentially-blocking system call. It is expensive to synchronize with those worker threads. As a result, Lwt'sreaddir
re-introduces the same kind of performance problem that C'sreaddir_r
already tries to solve by buffering.So, I think Lwt's
readdir
should just read ahead and buffer the results of the underlyingreaddir_r
on the Lwt side. When the Lwt buffer has unread entries remaining, it will not be necessary to run anything in a separate thread.Lwt_unix.readdir_n
is basically there for the user to do manually what should be done byLwt_unix.readdir
internally. And,files_of_directory
is a wrapper aroundreaddir_n
, becausereaddir_n
is awkward.If changing the implementation of
readdir
works, and is fast enough, I will deprecatereaddir_n
andfiles_of_directory
. I will look into the performance ofLwt_stream
itself at a later date, asLwt_stream
has a lot of other problems.cc @samoht, @yallop