webentwicklung-frage-antwort-db.com.de

Schneller zu os.walk oder glob?

Ich spiele mit Dateisuchen in Python auf einer großen Festplatte herum. Ich habe mir os.walk und glob angesehen. Ich benutze normalerweise os.walk, da ich es viel ordentlicher finde und es schneller zu sein scheint (für Verzeichnisse mit üblicher Größe).

Hat jemand Erfahrung mit beiden und könnte sagen, was effizienter ist? Wie gesagt, glob scheint langsamer zu sein, aber Sie können Platzhalter usw. verwenden, da Sie wie bei walk die Ergebnisse filtern müssen. Hier ist ein Beispiel für das Nachschlagen von Core 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)

Oder

for file in iglob("/path/to/dir/core.*")
    print "Deleting: " + file
    os.remove(file)
23
jdborg

Ich recherchierte über einen kleinen Cache von Webseiten in 1000 Verzeichnissen. Die Aufgabe bestand darin, die Gesamtzahl der Dateien in Verzeichnissen zu zählen. Die Ausgabe ist:

os.listdir: 0.7268s, 1326786 files found
os.walk: 3.6592s, 1326787 files found
glob.glob: 2.0133s, 1326786 files found

Wie Sie sehen, ist os.listdir der schnellste von drei. Und glog.glob ist für diese Aufgabe immer noch schneller als os.walk.

Die Quelle:

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

Wenn Sie durch Unterverzeichnisse rekursieren müssen, verwenden Sie os.walk. Ansonsten denke ich, dass es einfacher wäre, glob.iglob oder os.listdir zu verwenden.

14
unutbu

Verschwenden Sie keine Zeit für die Optimierung, bevor Sie die Messung/Profilierung durchführen. Konzentrieren Sie sich darauf, Ihren Code einfach und wartungsfreundlich zu gestalten. 

Zum Beispiel kompilieren Sie RE in Ihrem Code, wodurch Sie keinen Geschwindigkeitsschub erhalten, da das re-Modul über internen re._cache vorkompilierter REs verfügt.

  1. Halte es einfach
  2. wenn es langsam ist, dann Profil
  3. sobald Sie genau wissen, was optimiert werden muss, nehmen Sie einige Anpassungen vor und dokumentieren Sie diese immer

Beachten Sie, dass einige Optimierungen, die vor einigen Jahren durchgeführt wurden, dazu führen können, dass Code langsamer ausgeführt wird als "nicht optimierter" Code. Dies gilt insbesondere für moderne JIT-basierte Sprachen.

10
Michał Šrajer

Sie können os.walk verwenden und trotzdem den Glob-Style-Abgleich verwenden.

for root, dirs, files in os.walk(DIRECTORY):
    for file in files:
        if glob.fnmatch.fnmatch(file, PATTERN):
            print file

Sie sind sich nicht sicher, was Geschwindigkeit angeht, aber offensichtlich, da os.walk rekursiv ist, machen sie verschiedene Dinge.

2
Ken Kinder

*, ?, and character ranges expressed with [] will be correctly matched. This is done by using the os.listdir() and fnmatch.fnmatch() functions

Ich denke, selbst bei glob müssten Sie noch os.walk, es sei denn, Sie wissen direkt, wie tief Ihr Unterverzeichnisbaum ist.

Übrigens in der glob Dokumentation heißt es:

"*,? und mit [] ausgedrückte Zeichenbereiche werden korrekt mit abgeglichen. Dies geschieht mithilfe der Funktionen os.listdir () und fnmatch.fnmatch () ."

Ich würde einfach mit gehen 

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