大容量ハードディスク上のpython=でファイルルックアップをいじくり回しています。os.walkとglobを見てきました。私は通常、os.walkを使用しています。より速いようです(通常のサイズのディレクトリの場合)。
誰かがそれらの両方で何らかの経験を持っていますか、どちらがより効率的であると言えるでしょうか?言ったように、グロブは遅いようですが、ワイルドカードなどを使用できます。ウォークと同様に、結果をフィルタリングする必要があります。コアダンプを検索する例を次に示します。
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)
または
for file in iglob("/path/to/dir/core.*")
print "Deleting: " + file
os.remove(file)
私は、1000ページの小さなWebページのキャッシュについて調査しました。タスクは、dirs内のファイルの総数をカウントすることでした。出力は次のとおりです。
os.listdir: 0.7268s, 1326786 files found
os.walk: 3.6592s, 1326787 files found
glob.glob: 2.0133s, 1326786 files found
ご覧のとおり、os.listdir
は3つの中で最速です。このタスクでは、glog.glob
はos.walk
よりも高速です。
起源:
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)
サブディレクトリを再帰的に処理する必要がある場合は、os.walk
を使用します。それ以外の場合は、glob.iglob
またはos.listdir
を使用する方が簡単だと思います。
測定/プロファイリングの前に最適化のために時間を無駄にしないでください。コードをシンプルで保守しやすいものにすることに焦点を当てます。
たとえば、コードではREをプリコンパイルしますが、REモジュールにはプリコンパイルされたREの内部re._cache
があるため、速度は向上しません。
数年前に行われた最適化によっては、「最適化されていない」コードと比較してコードの実行が遅くなる可能性があることに注意してください。これは、特に最新のJITベースの言語に当てはまります。
Os.walkを使用しても、globスタイルのマッチングを使用できます。
for root, dirs, files in os.walk(DIRECTORY):
for file in files:
if glob.fnmatch.fnmatch(file, PATTERN):
print file
速度はわかりませんが、明らかにos.walkはrecursiveであるため、異なる動作をします。
*, ?, and character ranges expressed with [] will be correctly matched. This is done by using the os.listdir() and fnmatch.fnmatch() functions
グロブを使っても、os.walk
、サブディレクトリツリーの深さが直接わからない場合。
ところで globドキュメント には次のように書かれています:
"[]で表される*、?、および文字の範囲は正しく一致します。これは、os.listdir()およびfnmatch.fnmatch()関数を使用して行われます"
私は単に
for path, subdirs, files in os.walk(path):
for name in fnmatch.filter(files, search_str):
shutil.copy(os.path.join(path,name), dest)