【问题标题】:Why is filecmp.cmp slow for huge files even when its 'shallow' parameter is True?为什么 filecmp.cmp 对于大文件来说很慢,即使它的“浅”参数是 True?
【发布时间】:2014-04-21 06:49:47
【问题描述】:

我编写了一个 Python 脚本来比较两个目录中的文件,使用 filecmp.cmp。它可以工作,但刚才我尝试为一组大文件运行它。速度很慢。

文档说,当shallow 参数为真时(默认为真),filecmp.cmp 应该只比较os.stat 结果。

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

【问题讨论】:

    标签: python python-3.x file-comparison


    【解决方案1】:

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

    您可以在您的 Python 安装中看到 cmp 的实现,或者您可以查看 Python source repository 中的(当前的)源代码。

    这里是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 为真且文件大小相同且mtimefilecmp.cmp 将假定文件相同。

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

    * 我认为filecmp.cmp 的文档字符串具有误导性,以至于它表明存在错误(或者因为它没有正确描述行为,或者因为实际实现不正确,应该修复以匹配文档)。看起来我并不孤单。 Here is a bug report 在这个问题上,虽然它已经好几年没有更新了。我会用这个问题的链接来 ping 错误,也许有人会努力修复它!

    【讨论】:

    • tks 为您提供信息。仅供参考,jpeg脚本运行速度快的集合约为2G,而mts的集合约为24G。只是 ls -la 用于比较的 mts 的两个目录,通过肉眼检查,大多数文件的日期和大小都与字节相同,我的脚本将跳过具有差异名称的文件。根据您的检查,除了 mtime diff 之外的任何条件都可以将脚本运行到内容检查中?从您引用的代码摘录中,它没有显示调用助手的条件。
    • filecmp.cmp 是纯pythonic还是涉及c函数调用?我可以调用 python 中的任何 c 速度库来提高性能,以防脚本遇到字节到字节检查?
    • @timeislove:整个filecmp 模块是纯Python,尽管它调用其他模块中的C 函数(如os.stat)。您可以通过在 Python 安装中加载 Lib/filecmp.py 来阅读完整的源代码,或者您可以查看当前版本 in the Python source repository。唯一可以避免在cmp 中进行额外文件扫描(超出我在回答中摘录的内容)的是(相当粗略的)缓存,但这只有助于您将完全相同的文件相互比较一次以上。
    • 任何可能的 c 速度文件内容检查?查了linux系统cmp,好像没有。
    猜你喜欢
    • 2021-01-07
    • 1970-01-01
    • 2015-02-09
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多