Je fouille dans les recherches de fichiers en python sur un grand disque dur. J'ai examiné os.walk et glob. J'utilise habituellement os.walk car je le trouve beaucoup plus net et semble être plus rapide (pour les répertoires de taille habituelle).
Quelqu'un at-il une expérience avec les deux et pourrait dire lequel est le plus efficace? Comme je le disais, glob semble être plus lent, mais vous pouvez utiliser des caractères génériques, etc., comme pour marcher, vous devez filtrer les résultats. Voici un exemple de recherche de carottes.
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)
Ou
for file in iglob("/path/to/dir/core.*")
print "Deleting: " + file
os.remove(file)
J'ai fait une recherche sur un petit cache de pages Web dans 1000 dir. La tâche consistait à compter un nombre total de fichiers dans les répertoires. La sortie est:
os.listdir: 0.7268s, 1326786 files found
os.walk: 3.6592s, 1326787 files found
glob.glob: 2.0133s, 1326786 files found
Comme vous le voyez, os.listdir
est le plus rapide des trois. Et glog.glob
est toujours plus rapide que os.walk
pour cette tâche.
La source:
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)
Si vous avez besoin de recurse à travers des sous-répertoires, utilisez os.walk
. Sinon, je pense qu'il serait plus facile d'utiliser glob.iglob
ou os.listdir
.
Ne perdez pas votre temps pour l'optimisation avant de mesurer/profiler. Concentrez-vous sur la simplicité et la maintenance de votre code.
Par exemple, dans votre code, vous pré-compilez RE, ce qui ne vous donne aucune accélération de la vitesse, car re module a le re._cache
interne des RE précompilées.
Notez que certaines optimisations effectuées plusieurs années auparavant peuvent ralentir l’exécution du code par rapport au code "non optimisé". Cela s'applique particulièrement aux langues modernes basées sur JIT.
Vous pouvez utiliser os.walk tout en utilisant la correspondance de style glob.
for root, dirs, files in os.walk(DIRECTORY):
for file in files:
if glob.fnmatch.fnmatch(file, PATTERN):
print file
Pas sûr de la vitesse, mais évidemment puisque os.walk est récursif , ils font des choses différentes.
*, ?, and character ranges expressed with [] will be correctly matched. This is done by using the os.listdir() and fnmatch.fnmatch() functions
Je pense que même avec glob, vous auriez toujours besoin de os.walk
, à moins que vous ne sachiez directement quelle est la profondeur de votre arborescence de sous-répertoires.
Btw. dans la documentation glob il est écrit:
"*,? et les plages de caractères exprimées avec [] seront correctement appariées . Pour ce faire, utilisez les fonctions os.listdir () et fnmatch.fnmatch () "
Je voudrais simplement aller avec un
for path, subdirs, files in os.walk(path):
for name in fnmatch.filter(files, search_str):
shutil.copy(os.path.join(path,name), dest)