web-dev-qa-db-fra.com

Plus rapide à os.walk ou glob?

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)
23
jdborg

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)
19
a5kin

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.

14
unutbu

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.

  1. Rester simple
  2. si c'est lent, alors profil
  3. une fois que vous savez exactement ce qui doit être optimisé, faites quelques ajustements et documentez-le toujours

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.

10
Michał Šrajer

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.

2
Ken Kinder

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