更快地进行os.walk或glob



我在大硬盘上用python查找文件。我一直在看os.walk和glob。我通常使用os.walk,因为我发现它更整洁,似乎更快(对于通常大小的目录)。

有没有人对这两种方法都有经验,可以说哪种更有效?正如我所说,glob似乎更慢,但你可以使用通配符等,就像walk一样,你必须过滤结果。下面是一个查找核心转储的示例。

core = re.compile(r"core.d*")
for root, dirs, files in os.walk("/path/to/dir/")
    for file in files:
        if core.search(file):
            path = os.path.join(root,file)
            print "Deleting: " + path
            os.remove(path)

for file in iglob("/path/to/dir/core.*")
    print "Deleting: " + file
    os.remove(file)

我研究了一个1000个目录中的小型网页缓存。任务是计算目录中的文件总数。输出为:

os.listdir: 0.7268s, 1326786 files found
os.walk: 3.6592s, 1326787 files found
glob.glob: 2.0133s, 1326786 files found

如您所见,os.listdir是三个中最快的。并且对于该任务,glog.glob仍然比os.walk快。

来源:

import os, time, glob
n, t = 0, time.time()
for i in range(1000):
    n += len(os.listdir("./%d" % i))
t = time.time() - t
print "os.listdir: %.4fs, %d files found" % (t, n)
n, t = 0, time.time()
for root, dirs, files in os.walk("./"):
    for file in files:
        n += 1
t = time.time() - t
print "os.walk: %.4fs, %d files found" % (t, n)
n, t = 0, time.time()
for i in range(1000):
    n += len(glob.glob("./%d/*" % i))
t = time.time() - t
print "glob.glob: %.4fs, %d files found" % (t, n)

您可以使用os.walk,但仍然使用glob样式匹配。

for root, dirs, files in os.walk(DIRECTORY):
    for file in files:
        if glob.fnmatch.fnmatch(file, PATTERN):
            print file

不确定速度,但很明显,由于os.walk是递归,它们做的事情不同。

*, ?, and character ranges expressed with [] will be correctly matched. This is done by using the os.listdir() and fnmatch.fnmatch() functions

我认为即使有glob,你仍然需要os.walk,除非你直接知道你的子目录树有多深。

Btw。在glob文档中,它说:

用[]表示的*、?和字符范围将正确匹配。这是通过使用os.listdir()和fnmatch.fnmatch()来完成的功能"

我只会选择

for path, subdirs, files in os.walk(path):
        for name in fnmatch.filter(files, search_str):
            shutil.copy(os.path.join(path,name), dest)

在将os.walk与任何其他方法进行比较时,似乎从未提及的一点是它具有不同的功能。Scandir是在获取目录内容方面性能最快的基本实现。Listdir用于目录内容的简单列表。glob是一种潜在的递归模式匹配操作。Walk是对目录的递归遍历,具有完全的用户控制。

  • 用户可以使用topdown=True | False来决定遍历的顺序
  • 用户可以在遍历期间通过从任何给定目录的子目录列表中删除目录来修剪树(使用topdown=True)
  • 用户可以在遍历期间对文件和目录执行任意操作
  • 结合遍历顺序和文件可移除的控制,用户可以使用topdown=False并移除文件,然后如果目录为空,则可以移除目录

步行作为一种通用工具的力量是有代价的。如果你只需要listdir或glob,那么就应该使用它们,而不是步行。但是,当你需要走路的力量时,其他人根本做不到。

在测量/分析之前不要浪费时间进行优化。专注于使代码简单易维护。

例如,在您的代码中,您预编译RE,这不会提高您的速度,因为RE模块具有预编译RE的内部re._cache

  1. 保持简单
  2. 如果速度较慢,则配置文件
  3. 一旦你确切地知道需要优化什么,就做一些调整,并始终记录下来

请注意,与"未优化"代码相比,几年前进行的一些优化可能会使代码运行速度变慢。这尤其适用于现代基于JIT的语言。

相关内容

  • 没有找到相关文章

最新更新