我需要浏览一个大约有一万个文件的文件夹。我的旧vbscript在处理这个问题时非常慢。因为我从那时起就开始使用Ruby和Python,所以我在这三种脚本语言之间做了一个基准测试,看看哪种语言最适合这项工作。在
下面对共享网络上4500个文件子集的测试结果如下
Python: 106 seconds
Ruby: 5 seconds
Vbscript: 124 seconds
Vbscript速度最慢并不奇怪,但我无法解释Ruby和Python之间的区别。我的Python测试不是最优的吗?在Python中有没有更快的方法来实现这一点?在
测试拇指分贝只是为了测试,实际上还有更多的测试要做。在
我需要一些东西来检查路径上的每一个文件,并且不会产生太多的输出,以免干扰计时。每次运行的结果都有点不同,但差别不大。在
^{pr2}$'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)}
编辑:由于我怀疑打印造成了延迟,我测试了脚本,打印了所有4500个文件,也没有打印任何文件,但差别仍然存在,第一种情况下的R:5p:107,后一种情况下的R:4.5p:107
EDIT2:基于这里的答案和注释,Python版本在某些情况下可以通过跳过文件夹运行得更快
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
我在本地设置目录结构:
这将创建99个文件,路径深度为1-99级,4401个文件位于目录结构的根目录中。在
我使用了以下ruby脚本:
^{pr2}$我得到了以下结果:
我使用下面的python脚本手术室步行公司名称:
我得到了以下结果:
所以,看起来ruby的表现仍然更好。看看这个在你的网络共享文件集上的表现会很有趣。在
看到这个脚本在python3、jython甚至pypy上运行也很有趣。在
Dir
的Ruby实现在C语言中(根据this documentation,文件dir.c
)。但是,Python的等价物实现了in Python。在Python的性能不如C并不奇怪,但Python中使用的方法提供了更多的灵活性——例如,在遍历目录层次结构时,可以跳过名为
'.svn'
、'.git'
、'.hg'
的子树。在大多数时候,Python实现已经足够快了。在
更新:跳过文件/子目录根本不会影响遍历速率,但处理目录树所需的总时间肯定会减少,因为您可以避免遍历主树中潜在的大型子树。节省的时间当然与你跳过多少成正比。在您的例子中,它看起来像是图像的文件夹,您不太可能节省很多时间(除非图像处于修订控制之下,跳过修订控制系统拥有的子树可能会有一些影响)。在
其他更新:跳过文件夹是通过更改
dirs
值来完成的:相关问题 更多 >
编程相关推荐