use*_*459 51 python directory optimization
我想使用python快速找到任何文件夹的总大小.
import os
from os.path import join, getsize, isfile, isdir, splitext
def GetFolderSize(path):
TotalSize = 0
for item in os.walk(path):
for file in item[2]:
try:
TotalSize = TotalSize + getsize(join(item[0], file))
except:
print("error with file: " + join(item[0], file))
return TotalSize
print(float(GetFolderSize("C:\\")) /1024 /1024 /1024)
Run Code Online (Sandbox Code Playgroud)
这是我编写的简单脚本来获取文件夹的总大小,花了大约60秒(+ -5秒).通过使用多处理,我在四核机器上将其降低到23秒.
使用Windows文件浏览器只需约3秒钟(右键单击 - >属性可自行查看).那么是否有更快的方法来查找接近Windows可以执行的速度的文件夹的总大小?
Windows 7,python 2.6(搜索但是大多数时候人们使用了与我自己非常相似的方法)在此先感谢.
vla*_*adr 76
你处于劣势.
Windows资源管理器几乎肯定使用FindFirstFile/ FindNextFile遍历目录结构并lpFindFileData在一次传递中收集大小信息(通过),从而使每个文件基本上是单个系统调用.
遗憾的是,在这种情况下,Python不是你的朋友.从而,
os.walk 第一次调用os.listdir(内部调用FindFirstFile/ FindNextFile)
os.walk 然后调用isdir返回的每个文件os.listdir(内部调用GetFileAttributesEx- 或者,在Win2k之前,GetFileAttributes+ FindFirstFile组合)重新确定是否递归os.walk和os.listdir将执行额外的内存分配,串和阵列操作等填写它们的返回值getsize你调用返回的每个文件os.walk(再次调用GetFileAttributesEx)这是每个文件比Windows资源管理器多3倍的系统调用,加上内存分配和操作开销.
你可以使用Anurag的解决方案,也可以尝试直接和递归地调用FindFirstFile/ FindNextFile(这应该与一个cygwin或其他win32端口 的性能相当du -s some_directory.)
请参阅os.py的实施os.walk,posixmodule.c为实施listdir和win32_stat(双方调用isdir和getsize.)
请注意,Python os.walk在所有平台(Windows和*nices)上都是次优的,包括Python3.1.在Windows和*nices上os.walk都可以在没有调用的情况下在单个传递中实现遍历,isdir因为FindFirst/ FindNext(Windows)和opendir/ readdir(*nix)已经通过lpFindFileData->dwFileAttributes(Windows)和dirent::d_type(*nix)返回文件类型.
也许违反直觉,在大多数现代配置(例如Win7和NTFS,甚至一些SMB实现)GetFileAttributesEx上,速度是单个文件的两倍FindFirstFile(可能比使用FindNextFile.目录迭代更慢).
更新: Python 3.5包含新的PEP 471 os.scandir()函数,它通过返回文件属性和文件名来解决此问题.此新功能用于加速内置os.walk()(在Windows和Linux上).您可以在PyPI上使用scandir模块来获取旧版Python的这种行为,包括2.x.
Anu*_*yal 22
如果您想要与资源管理器相同的速度,为什么不使用Windows脚本来使用pythoncom访问相同的功能,例如
import win32com.client as com
folderPath = r"D:\Software\Downloads"
fso = com.Dispatch("Scripting.FileSystemObject")
folder = fso.GetFolder(folderPath)
MB = 1024 * 1024.0
print("%.2f MB" % (folder.Size / MB))
Run Code Online (Sandbox Code Playgroud)
它将与资源管理器相同,您可以在http://msdn.microsoft.com/en-us/library/bstcxhf7(VS.85).aspx上阅读有关Scripting运行时的更多信息.
我将Python代码的性能与包含190k文件的15k目录树进行了比较,并将其与du(1)可能与操作系统一样快的命令进行了比较.与du相比,Python代码耗时3.3秒,耗时0.8秒.这是在Linux上.
我不确定有多少东西可以挤出Python代码.另请注意,du的第一次运行需要45秒,这显然是在相关的i节点位于块缓存之前; 因此,这种性能在很大程度上取决于系统管理其商店的程度.如果其中一个或两个都不会让我感到惊讶: