更快到os.walk还是glob?

时间:2012-01-19 18:10:45

标签: python traversal glob os.walk directory-walk

我在大型硬盘上的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)

4 个答案:

答案 0 :(得分:22)

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

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)

答案 1 :(得分:10)

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

例如,在您的代码中,您预先编译了RE,它不会为您提供任何速度提升,因为re模块具有内部re._cache预编译的RE。

  1. 保持简单
  2. 如果它很慢,那么配置文件
  3. 一旦你确切地知道需要优化什么,做一些调整并总是记录它
  4. 请注意,与“非优化”代码相比,几年前完成的某些优化会使代码运行速度变慢。这尤其适用于现代基于JIT的语言。

答案 2 :(得分:2)

你可以使用os.walk并仍然使用glob-style匹配。

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

不确定速度,但很明显,因为os.walk是递归,他们会做不同的事情。

答案 3 :(得分:0)

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

我认为即使使用glob,您仍然需要os.walk,除非您直接了解子目录树的深度。

顺便说一下。在glob documentation中它说:

  

" *,?和用[]表示的字符范围将是正确的   匹配。这是通过使用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)