Быстрее os.walk или шар?
Я возиться с поиском файлов в 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)
6 ответов
Я провел исследование небольшого кэша веб-страниц в 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.iglob
или же os.listdir
,
Не тратьте свое время на оптимизацию перед измерением / профилированием. Сосредоточьтесь на том, чтобы сделать ваш код простым и легким в обслуживании.
Например, в вашем коде вы прекомпилируете RE, что не дает вам никакого увеличения скорости, потому что модуль re имеет внутренний re._cache
предварительно скомпилированных RE.
- Будь проще
- если это медленно, то профиль
- как только вы точно знаете, что нужно оптимизировать, сделайте некоторые изменения и всегда документируйте это
Обратите внимание, что некоторая оптимизация, выполненная несколькими годами ранее, может замедлить выполнение кода по сравнению с "неоптимизированным" кодом. Это особенно относится к современным языкам на основе JIT.
Вы можете использовать os.walk и по-прежнему использовать глобальное сопоставление.
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, то их следует использовать, а не ходить. Но когда вам нужна сила ходьбы, другие просто не подойдут.