Python 为什么filecmp.cmp即使在';浅';参数是否为真?

Python 为什么filecmp.cmp即使在';浅';参数是否为真?,python,python-3.x,file-comparison,Python,Python 3.x,File Comparison,我编写了一个Python脚本来比较两个目录中的文件,使用filecmp.cmp。它可以工作,但刚才我试着为一个巨大的文件集合运行它。非常慢 文档中说,当shallow参数为true时(默认情况下为true),filecmp.cmp应该只比较os.stat结果 对于另一大组jpg文件,脚本运行得更快。我想知道为什么文件大小比文件数量的影响更大,好像它只检查os.stat。我认为shallow参数的文档有误导性*。传递shallow=True并不一定会阻止filecmp.cmp函数比较文件的内容。如

我编写了一个Python脚本来比较两个目录中的文件,使用
filecmp.cmp
。它可以工作,但刚才我试着为一个巨大的文件集合运行它。非常慢

文档中说,当
shallow
参数为true时(默认情况下为true),
filecmp.cmp
应该只比较
os.stat
结果


对于另一大组
jpg
文件,脚本运行得更快。我想知道为什么文件大小比文件数量的影响更大,好像它只检查
os.stat

我认为
shallow
参数的文档有误导性*。传递
shallow=True
并不一定会阻止
filecmp.cmp
函数比较文件的内容。如果您的文件大小相同,但具有不同的
mtime
s,则仍将检查其内容

您可以在Python安装中看到
cmp
的实现,也可以在中查看(目前为止的)源代码

以下是
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
\u sig
helper函数返回从文件的
stat
数据结构中提取的值的元组。元组值是文件类型、文件大小及其
mtime
(通常是上次修改文件内容时)

我在代码摘录中包含的测试试图根据这些元数据快速确定两个文件是否相同。如果任一文件不是“常规”文件(因为它是目录或特殊系统文件),则认为它们不相等。而且,如果它们的大小不一样,它们就不可能相等

shallow
参数的作用是允许快速进行阳性检测。如果
shallow
为真,且文件大小相同且
mtime
filecmp.cmp
将假定文件相等

我怀疑在您的程序中发生的是,您当前的目录中有许多大小完全相同的文件(可能是因为内容非常相似,或者是因为文件大小由数据格式固定)。您以前的数据集没有那么多大小相同的文件,因此您的代码能够快速排除它们


*我认为
filecmp.cmp
的docstring具有误导性,它指出了一个bug(要么因为它没有正确描述行为,要么因为实际实现不正确,应该进行修复以匹配文档)。看起来我并不孤单。在这个问题上,虽然已经好几年没有更新了。我会用这个问题的链接ping这个bug,也许有人会修复它

tks为您提供信息。仅供参考,脚本运行速度快的jpeg的收集量约为2G,而mts的收集量约为24G。只需将mts的两个目录ls-la进行比较,通过目测,大多数文件的日期和大小都相同,只有字节,我的脚本将跳过具有不同名称的文件。根据您的检查,除了mtime diff之外,还有什么条件可以将脚本运行到内容检查中?从您引用的代码摘录中,它没有显示调用helper的条件。filecmp.cmp是纯pythonic还是包含c函数调用?我可以调用python中的任何c速度库来提高性能,以防脚本遇到字节对字节的检查?@timeislove:整个
filecmp
模块都是纯python的,尽管它在其他模块中调用c函数(如
os.stat
)。您可以通过在Python安装中加载
Lib/filecmp.py
来阅读完整的源代码,也可以查看当前版本。在
cmp
中,唯一可以避免额外文件扫描的方法(除了我在回答中摘录的内容)是一个(相当粗糙的)缓存,但这唯一有帮助的是,您可以多次将完全相同的文件相互比较。有没有可能的c速度文件内容检查?检查了linux系统cmp,似乎没有。