为什么即使'shallow'参数为True,filecmp.cmp对于大文件仍然很慢?
我写了一个Python脚本,用来比较两个文件夹里的文件,使用的是filecmp.cmp
这个功能。这个脚本能正常工作,但我刚刚尝试对一堆很大的文件进行比较时,速度非常慢。
文档上说,当shallow
参数为真(默认就是这样),filecmp.cmp
只会比较os.stat
的结果。
不过,我发现对于另一组大的jpg
文件,脚本运行得快多了。我在想,文件大小对速度的影响怎么比文件数量大,就好像它只检查os.stat
一样。
1 个回答
我觉得关于 shallow
参数的说明有点误导人。传入 shallow = True
并不一定会阻止 filecmp.cmp
函数比较文件的内容。如果你的文件大小相同但修改时间 mtime
不同,它们的内容还是会被检查。
你可以在你的 Python 安装中查看 cmp
的实现,或者在这个 Python 源代码库 中查看当前的源代码。
这里是 cmp
的相关部分:
def cmp(f1, f2, shallow=True):
# long docstring removed
s1 = _sig(os.stat(f1))
s2 = _sig(os.stat(f2))
if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG:
return False
if shallow and s1 == s2:
return True
if s1[1] != s2[1]:
return False
# rest of function, which calls a helper to do the actual file contents comparisons
_sig
这个辅助函数会返回一个元组,里面包含从文件的 stat
数据结构中提取的值。这个元组的值包括文件类型、文件大小和它的 mtime
(通常是文件内容最后一次修改的时间)。
我在代码片段中包含的测试是为了快速判断两个文件是否相同,主要依据这些元数据。如果其中一个文件不是“常规”文件(比如是目录或者特殊的系统文件),那么它们就被认为是不相等的。此外,如果它们的大小不一样,那肯定也不相等。
shallow
参数的作用是允许快速的正向测试。如果 shallow
为真,并且两个文件的大小和 mtime
相同,filecmp.cmp
就会认为这两个文件是相等的。
我怀疑在你的程序中发生的情况是,你当前目录下有很多文件大小完全相同(可能是因为内容非常相似,或者因为文件大小是由数据格式决定的)。而你之前的数据集没有那么多相同大小的文件,所以你的代码能够快速排除它们。
* 我觉得 filecmp.cmp
的文档说明非常误导,甚至可以说是个 bug(要么是因为没有正确描述行为,要么是实际实现有问题,应该修正以符合文档)。看起来我并不是唯一这么认为的人。这里有一个关于这个问题的 bug 报告,不过已经好几年没有更新了。我会在这个 bug 上加个链接到这个问题,也许会有人来修复它!