Joe*_*art 6 python optimization os.walk
我正在使用os.walk构建数据存储的映射(此映射稍后在我正在构建的工具中使用)
这是我目前使用的代码:
def find_children(tickstore):
children = []
dir_list = os.walk(tickstore)
for i in dir_list:
children.append(i[0])
return children
Run Code Online (Sandbox Code Playgroud)
我对它做了一些分析:
dir_list = os.walk(tickstore)立即运行,如果我什么都不做,dir_list那么此功能立即完成.
迭代dir_list需要花费很长时间,即使我什么都不做append,只需迭代就可以花费时间.
Tickstore 是一个大型数据存储区,有大约10,000个目录.
目前完成此功能大约需要35分钟.
有没有办法加快速度?
我已经看过了替代方案,os.walk但它们似乎都没有在速度方面提供太多优势.
Tho*_*zco 11
是的:使用Python 3.5(目前仍然是RC,但应该暂时出来).在Python 3.5中,os.walk被重写为更高效.
这项工作是PEP 471的一部分.
从PEP中提取:
Python的内置
os.walk()速度明显慢于它需要的速度,因为 - 除了调用os.listdir()每个目录外 - 它还执行stat()系统调用或GetFileAttributes()每个文件以确定条目是否是目录.但潜在的系统调用-
FindFirstFile/FindNextFile在Windows和readdir对POSIX系统-已经告诉你返回的文件是否是目录或没有,因此不需要进一步的系统调用.此外,Windows系统调用返回stat_result目录条目上对象的所有信息,例如文件大小和上次修改时间.简而言之,您可以减少树函数所需的系统调用次数,例如
os.walk()从大约2N到N,其中N是树中文件和目录的总数.(因为目录树通常比它们更深,所以通常比这更好.)实际上,删除所有这些额外的系统调用
os.walk()在Windows上的速度大约是后者的8-9倍,在POSIX系统上大约是后者的2-3倍.所以我们不是在谈论微观优化.在这里查看更多基准.
一种在python2.7中优化它的方法,scandir.walk()代替使用os.walk(),参数完全相同.
import scandir
directory = "/tmp"
res = scandir.walk(directory)
for item in res:
print item
Run Code Online (Sandbox Code Playgroud)
PS:正如评论中提到的@recoup一样,scandir需要在python2.7中使用之前安装.