一种比 os.listdir 更快的目录遍历方式?

新手上路,请多包涵

我正在尝试提高 elfinder 的性能,这是一个基于 ajax 的文件管理器 (elRTE.ru)。

它在递归中使用 os.listdir 递归地遍历所有目录并且性能受到影响(比如列出一个包含 3000 多个文件的目录需要 7 秒)..

我正在尝试提高它的性能,这是它的行走功能:

         for d in os.listdir(path):
            pd = os.path.join(path, d)
            if os.path.isdir(pd) and not os.path.islink(pd) and self.__isAccepted(d):
                tree['dirs'].append(self.__tree(pd))

我的问题是:

  1. 如果我更改 os.walk 而不是 os.listdir ,它会提高性能吗?
  2. 使用 dircache.listdir() 怎么样?在初始请求时缓存整个目录/子目录内容并返回缓存结果,如果没有新文件上传或文件没有更改?
  3. 还有其他更快的目录遍历方法吗?
  4. 任何其他用 python 快速编写的服务器端文件浏览器(但我更喜欢让这个更快)?

原文由 Phyo Arkar Lwin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

我只是想弄清楚如何在大型文件系统(分布在大约 50,000 个目录中的 350,000 个文件)上加速 os.walk。我在 linux 机器上使用 ext3 文件系统。我发现有一种方法可以加快我的情况。

具体来说,使用自上而下的遍历,每当 os.walk 返回一个以上目录的列表时,我使用 os.stat 获取每个目录的 inode 编号,并按 inode 编号对目录列表进行排序。这使得 walk 主要以 inode 顺序访问子目录,从而减少磁盘查找。

对于我的用例,它加快了我的完整目录步行时间,从 18 分钟缩短到 13 分钟……

原文由 garlon4 发布,翻译遵循 CC BY-SA 2.5 许可协议

你检查过 scandir (以前是 betterwalk )吗?我自己没有尝试过,但是这里有一个 关于它的讨论另一个在这里。它声称通过避免对 os.stat() 的冗余调用,在 MacOSX/Linux 上加速 3~10 倍,在 Windows 上加速 7~50 倍。从 Python 3.5 开始,它现在也包含在标准库中。

Python 的内置 os.walk() 比它需要的要慢得多,因为——除了在每个目录上调用 listdir()——它在每个文件上调用 stat() 以确定文件名是目录还是不是。但是 Windows 上的 FindFirstFile / FindNextFile 和 Linux/OS X 上的 readdir 都已经告诉你返回的文件是否是目录,所以不需要进一步的 stat 系统调用。简而言之,您可以将系统调用的数量从大约 2N 减少到 N,其中 N 是树中文件和目录的总数。

实际上,删除所有这些额外的系统调用会使 os.walk() 在 Windows 上的速度提高约 7-50 倍,在 Linux 和 Mac OS X 上的速度提高约 3-10 倍

来自 项目的自述文件

原文由 gaborous 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题