benchmarks: python tem uma maneira mais rápida de percorrer uma pasta de rede?
Eu preciso percorrer uma pasta com aproximadamente dez mil arquivos. Meu antigo vbscript é muito lento para lidar com isso. Desde que comecei a usar Ruby e Python desde então, fiz uma referência entre as três linguagens de script para ver qual seria o melhor ajuste para esse trabalho.
Os resultados dos testes abaixo em um subconjunto de 4.500 arquivos em uma rede compartilhada são
Python: 106 seconds
Ruby: 5 seconds
Vbscript: 124 seconds
Que Vbscript seria mais lento não foi surpresa, mas não posso explicar a diferença entre Ruby e Python. Meu teste para Python não é ideal? Existe uma maneira mais rápida de fazer isso em Python?
O teste para thumbs.db é apenas para o teste, na realidade, há mais testes para fazer.
Eu precisava de algo que verifica todos os arquivos no caminho e não produz muita saída para não atrapalhar o tempo. Os resultados são um pouco diferentes a cada execução, mas não muito.
#python2.7.0
import os
def recurse(path):
for (path, dirs, files) in os.walk(path):
for file in files:
if file.lower() == "thumbs.db":
print (path+'/'+file)
if __name__ == '__main__':
import timeit
path = '//server/share/folder/'
print(timeit.timeit('recurse("'+path+'")', setup="from __main__ import recurse", number=1))
'vbscript5.7
set oFso = CreateObject("Scripting.FileSystemObject")
const path = "\\server\share\folder"
start = Timer
myLCfilename="thumbs.db"
sub recurse(folder)
for each file in folder.Files
if lCase(file.name) = myLCfilename then
wscript.echo file
end if
next
for each subfolder in folder.SubFolders
call Recurse(subfolder)
next
end Sub
set folder = oFso.getFolder(path)
recurse(folder)
wscript.echo Timer-start
#ruby1.9.3
require 'benchmark'
def recursive(path, bench)
bench.report(path) do
Dir["#{path}/**/**"].each{|file| puts file if File.basename(file).downcase == "thumbs.db"}
end
end
path = '//server/share/folder/'
Benchmark.bm {|bench| recursive(path, bench)}
EDIT: desde que eu suspeitei que a impressão causou um atraso eu testei os scripts com a impressão de todos os arquivos 4500 e também impressão nenhum, a diferença permanece, R: 5 P: 107 no primeiro caso e R: 4,5 P: 107 no último
EDIT2: com base nas respostas e comentários aqui uma versão do Python que, em alguns casos, poderia correr mais rápido, ignorando pastas
import os
def recurse(path):
for (path, dirs, files) in os.walk(path):
for file in files:
if file.lower() == "thumbs.db":
print (path+'/'+file)
def recurse2(path):
for (path, dirs, files) in os.walk(path):
for dir in dirs:
if dir in ('comics'):
dirs.remove(dir)
for file in files:
if file.lower() == "thumbs.db":
print (path+'/'+file)
if __name__ == '__main__':
import timeit
path = 'f:/'
print(timeit.timeit('recurse("'+path+'")', setup="from __main__ import recurse", number=1))
#6.20102692
print(timeit.timeit('recurse2("'+path+'")', setup="from __main__ import recurse2", number=1))
#2.73848228
#ruby 5.7