Plus rapide à l'os.marcher ou glob?

Je déconne avec des recherches de fichiers en python sur un grand disque dur. J'ai été à la recherche à l'os.de marcher et de glob. J'utilise habituellement os.marcher comme je le trouve beaucoup plus propre et semble être plus rapide (pour les répertoires de taille habituels).

Quelqu'un a-t-il une expérience avec les deux et pourrait-il dire lequel est le plus efficace? Comme je le dis, glob semble être plus lent, mais vous pouvez utiliser des caractères génériques, etc., comme avec walk, vous devez filtrer les résultats. Voici un exemple de recherche de base dumps.

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)
22
demandé sur aculich 2012-01-19 22:10:45

5 réponses

J'ai fait une recherche sur un petit cache de pages web en 1000 dirs. La tâche consistait à compter un nombre total de fichiers dans dirs. 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 encore 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)
18
répondu a5kin 2014-12-19 11:43:28

Si vous avez besoin de recurser à travers les sous-répertoires, utilisez os.walk. Sinon, je pense qu'il serait plus facile à utiliser glob.iglob ou os.listdir.

14
répondu unutbu 2012-01-19 18:13:10

Ne perdez pas votre temps pour l'optimisation avant de mesurer / profiler. Concentrez-vous sur la simplicité et la facilité d'entretien de votre code.

Par exemple, dans votre code, vous précompilez RE, ce qui ne vous donne aucun boost de vitesse, car le module re a re._cache interne de REs précompilé.

  1. Gardez les choses simples
  2. Si c'est lent, alors profile
  3. Une fois que vous savez exactement ce qui doit être optimisé, faites quelques réglages et documentez-le toujours

Notez que certaines optimisations fait plusieurs années auparavant peut rendre le code plus lent par rapport au code" non optimisé". Cela s'applique particulièrement aux langages modernes basés sur JIT.

10
répondu Michał Šrajer 2012-01-19 18:47:10

Vous pouvez utiliser le système d'exploitation.marchez et utilisez toujours 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 depuis os.pied est récursive, ils font des choses différentes.

2
répondu Ken Kinder 2012-01-19 18:25:39

*, ?, 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 devriez toujours os.walk, sauf si vous savez directement à quelle profondeur est votre arbre de sous-répertoire.

Btw. dans la documentation glob {[9] } Il est dit:

"*, ?, et les plages de caractères exprimées avec [] seront correctement égaler. Ceci est fait en utilisant le système d'exploitation.listdir () et fnmatch.fnmatch() les fonctions "

, 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
répondu Sebastian 2014-04-26 04:49:48