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)
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)
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
.
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é.
- Gardez les choses simples
- Si c'est lent, alors profile
- 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.
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.
*, ?, 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)