为什么 filecmp.cmp 对于大文件很慢,即使其'shallow'参数为 True?



我编写了一个Python脚本,使用filecmp.cmp比较两个目录中的文件。它是有效的,但刚才我试着为一组巨大的文件运行它。它非常慢。

文档指出,当shallow参数为true(默认情况下为true)时,filecmp.cmp应仅比较os.stat的结果。

对于另一个大型jpg文件集合,该脚本运行速度要快得多。我想知道为什么文件大小比文件数量有更大的影响,就好像它只检查os.stat一样。

我认为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的docstring是如此误导,以至于它指示了一个错误(要么是因为它没有正确描述行为,要么是因为实际实现不正确,应该进行修复以匹配文档)。看起来我并不孤单。这是一份关于这个问题的错误报告,尽管它已经好几年没有更新了。我会用这个问题的链接来ping这个bug,也许会有人来修复它!

最新更新