<p>对代码的快速分析表明,超过90%的时间是在单独的<code>FindFilesW()</code>调用中消耗的。这意味着通过调整Python代码所做的任何改进都是微不足道的。</p>
<p>微小的调整(如果您坚持使用FindFilesW)可以包括确保DIR_EXCLUDES是一个集合而不是一个列表,避免在其他模块上重复查找,并懒洋洋地索引到item[],以及将sys.platform检查移到外部。这包含了这些变化和其他变化,<strong>但不会带来超过1-2%的加速</strong>。</p>
<pre><code>DIR_EXCLUDES = set(['.', '..'])
MASK = win32con.FILE_ATTRIBUTE_DIRECTORY | win32con.FILE_ATTRIBUTE_SYSTEM
REQUIRED = win32con.FILE_ATTRIBUTE_DIRECTORY
FindFilesW = win32file.FindFilesW
def get_dir_size(path):
total_size = 0
try:
items = FindFilesW(path + r'\*')
except pywintypes.error, ex:
return total_size
for item in items:
total_size += item[5]
if (item[0] & MASK == REQUIRED):
name = item[8]
if name not in DIR_EXCLUDES:
total_size += get_dir_size(path + '\\' + name)
return total_size
</code></pre>
<p>唯一显著的加速来自于使用不同的API或不同的技术。您在一条注释中提到在后台执行此操作,因此可以将其结构为使用其中一个包来监视文件夹中的更改来执行增量更新。可能是<a href="http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html" rel="noreferrer">FindFirstChangeNotification API</a>或者类似的东西。您可以设置为监视整个树,或者根据该例程的工作方式(我没有使用它),您最好在整个树的不同子集上注册多个请求,如果这样可以减少您必须执行的搜索量(在收到通知时),以确定实际更改的内容和现在的大小。</p>
<p><strong>编辑:</strong>我在评论中询问您是否考虑到了WindowsXP和更高版本所做的繁重的文件系统元数据缓存。我刚刚对照Windows本身检查了您的代码(和我的代码)的性能,选择了C:\文件夹中的所有项,并按Alt-Enter键打开属性窗口。在这一次(使用您的代码)并获得40秒的运行时间之后,我现在从<em>两个方法</em>获得20秒的运行时间。换句话说,至少在我的机器上,您的代码实际上与Windows本身一样快。</p>