Подтвердить что ты не робот

Быстрее для oswalk или glob?

Я возился с поиском файлов в python на большом жестком диске. Я смотрел на os.walk и glob. Обычно я использую os.walk, поскольку я нахожу его намного опрятным и, кажется, быстрее (для обычных каталогов по размеру).

У кого-нибудь есть опыт с ними обоими и можно сказать, что более эффективно? Как я уже сказал, glob кажется медленнее, но вы можете использовать подстановочные знаки и т.д., Как и при прогулке, вам нужно фильтровать результаты. Вот пример поиска основных дампов.

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)
4b9b3361

Ответ 1

Я провел исследование небольшого кеша веб-страниц в 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)

Ответ 2

Если вам нужно выполнить рекурсию через подкаталоги, используйте os.walk. В противном случае, я думаю, было бы проще использовать glob.iglob или os.listdir.

Ответ 3

Не тратьте время на оптимизацию перед измерением/профилированием. Сосредоточьтесь на том, чтобы сделать ваш код простым и удобным в обслуживании.

Например, в вашем коде вы предварительно компилируете RE, который не дает вам какого-либо повышения скорости, потому что модуль re имеет внутренний re._cache предварительно скомпилированных REs.

  • Держите его простым.
  • если он медленный, то профиль
  • как только вы точно знаете, что нужно оптимизировать, сделайте некоторые настройки и всегда документируйте его.

Обратите внимание, что некоторая оптимизация, выполненная несколькими годами ранее, может сделать код медленнее по сравнению с "не оптимизированным" кодом. Это особенно актуально для современных языков, основанных на JIT.

Ответ 4

Вы можете использовать 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 рекурсивный, они делают разные вещи.

Ответ 5

*, ?, 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)