镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

fs.Dir.read() is very slow #29941

Closed
Closed

Description

@paulmillr
  • Version: 12.12.0
  • Platform: macOS catalina
  • Subsystem: FS

I maintain the popular readdirp module. Decided to try fs.opendir from node 12.12. The results are suboptimal: it's 3x slower to walk file trees when compared to fs.readdir.

To reproduce:

  1. Check out the gist: https://github.com/proxy/gist.github.com/paulmillr/4e3a4da2ad8e98cf0fe7dc819242532a
  2. By switching logic from if (opendir) to if (!opendir) I get 3x speedup, which means opendir is 3x slower than readdir.

Refs: #583, #29349

Activity

  1. added
    fsIssues and PRs related to file-system APIs and the fs module.
    performanceIssues and PRs related to the performance of Node.js.
    on Oct 12, 2019
  2. addaleax commented on Oct 12, 2019

    @addaleax
    Member

    Fwiw, #29893 isn’t released yet and is going to improve performance significantly.

    That being said, the big advantage of fs.opendir() is that it has a low upper limit on the memory necessary to read a directory, and not necessarily being faster than fs.readdir().

  3. paulmillr commented on Oct 12, 2019

    @paulmillr
    Author

    I think it must have comparable performance (-+ 30%), because it's reasonable to assume the software doesn't know how big a directory is ahead of time. Would be especially useful for readdirp.

  4. addaleax commented on Oct 12, 2019

    @addaleax
    Member

    With that PR, I’m getting something closer to an 80 % perf difference.

    One possibility that was suggested in it was making the number of entries read in one go configurable. I think that would bring this into acceptable parameters for you.

  5. paulmillr commented on Oct 12, 2019

    @paulmillr
    Author

    Great!

  6. changed the title [-]fs.opendir is very slow[/-] [+]fs.Dir.read() is very slow[/+] on Oct 12, 2019
  7. Fishrock123 commented on Oct 12, 2019

    @Fishrock123
    Contributor

    So, this will always be slower than fs.readdir(). Always, because to use it reasonably, you're going to need an async iterator (Promises) or an object stream (ugh).

    You'd be able to get much closer by having a different but frankly weird/awful api: an async iteratable of sync iterables...

    That being said that kind of subverts the point of the API. Sure, it should buffer to some extent because performance can reasonably be substantially improved without significant drawback. However, the large idea of such an API is to allow scheduled work on said directory entries to be started/return as iterator progresses, and to avoid such a large memory allocation on large directories.

  8. piyukore06 commented on Oct 12, 2019

    @piyukore06
    Contributor

    Would you like a PR for that?

  9. addaleax commented on Oct 12, 2019

    @addaleax
    Member

    @Fishrock123 We have a highWaterMark option for streams, so adding something similar here seems fine to me. In the end it just gives the user more control over the memory-vs-time tradeoff that’s involved here.

    @piyukore06 Unless there’s a strong objection, I’d say go for it. :)

  10. Fishrock123 commented on Oct 12, 2019

    @Fishrock123
    Contributor

    Oh, I wasn't clear but I certainly support being able to configure this. In fact, I was thinking about that as I was reviewing your PR. 😄

  11. Fishrock123 commented on Oct 15, 2019

    @Fishrock123
    Contributor

    @piyukore06 Please let us know if you need any help making that PR. It'l require a bit of C++, but only a little bit.

  12. piyukore06 commented on Oct 17, 2019

    @piyukore06
    Contributor

    Yes @Fishrock123 I feel a bit stuck, I will push my changes as soon as possible. Maybe you people could take a look and point me in right direction..

    Thanks in advance :)

  13. piyukore06 commented on Oct 19, 2019

    @piyukore06
    Contributor

    @addaleax @Fishrock123 I don't think I completely get the whole building, compiling and testing process. It's taking more time than expected, so If anyone else wants to go ahead and finish it, please do. I will try and understand more about the ecosystem and try to find another issue to contribute to. Thank you for your patience.

  14. self-assigned this
    on Oct 23, 2019
  15. added
    macosIssues and PRs related to the macOS platform.
    on Oct 23, 2019
  16. removed
    macosIssues and PRs related to the macOS platform.
    on Oct 24, 2019
  17. paulmillr commented on Feb 5, 2020

    @paulmillr
    Author

    @piyukore06 I don't see any performance improvements in the test from first post. Basically no changes with node 13-latest and bufferSize: 1024 / 4096 / whatevs. BufferSize: 1 makes this slower, so the arg works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

fsIssues and PRs related to file-system APIs and the fs module.performanceIssues and PRs related to the performance of Node.js.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions