【问题标题】:Performance problems in Python: os.walk() + filecmp.dircmp().report_full_closure()Python 中的性能问题:os.walk() + filecmp.dircmp().report_full_closure()
【发布时间】:2012-06-27 16:59:33
【问题描述】:

我目前需要在增量数据迁移发生后比较目录。我编写了一个 python 脚本来遍历源/目标列表,执行从源到目标的增量复制,然后立即比较每个目录中的文件和文件夹的数量。为了进行这种比较,我们非常简单地使用:

for (path, dirs, files) in os.walk(destd):

destFileCount += len(文件)

destDirCount += len(dirs)

如果返回的文件/目录的数量不同,我们调用另一段代码来查看到底有什么不同。为此,我们运行以下命令并将输出发送到文件:

filecmp.dircmp(sourced, destd).report_full_closure()

我们使用report_full_closure 部分,因为我不知道另一种进行递归比较的方法。然后,该脚本在生成的文件中搜索以“only in”开头的行并将它们打印到屏幕上,从而有效地向我们展示了差异。

无论多么低效,这对于包含大约 90,000 个文件的目录来说就像一个魅力,但是一旦我们达到这个上限,脚本就会变得迟缓,以至于无法将其用于此目的。我想我的问题可以分为以下几点:

  1. 我在使用这两个模块 [os.walk + filecmp.dircmp().report_full_closure()] 时是否犯了逻辑错误?即,我真的可以跳过 filecmp 节省时间,还是应该只执行 filecmp 并完全跳过文件/目录计数?

  2. 有没有办法通过“缓存”一个文件中的文件以在另一个中使用来组合这两个功能?

  3. 有没有更快的方法来执行这些功能?高低搜索过,估计没有。

非常感谢您对此事的看法。这个脚本已经变形和增长了很多,所以如果答案非常明显,请原谅我...... 谢谢, M

【问题讨论】:

  • 您只对新文件和目录感兴趣吗? dircmp 也会比较现有文件的内容。
  • 基本上在执行迁移之后,理想情况下源和目标之间应该没有区别(当然,除非有人在迁移过程中向源写入了一些数据),所以我想知道如果在从源头到目的地正式“切换”之前有任何差异。
  • 但是如果文件或目录的总数不同,您只进行完整比较?如果您正在寻找任何差异,我不明白那部分。
  • 它基于(可能不正确的)假设,即文件/文件夹的计数比比较快得多。如果是这种情况,我们将通过不对具有相同数量的文件/文件夹的目录进行比较来节省时间。这是我的问题的一部分,我想 - 执行这两个功能所需的时间差异可以忽略不计,因此我应该只运行完整的比较?
  • 另外,感谢 cmets Janne!

标签: python


【解决方案1】:

我会这样做:

dir_diff = filecmp.dircmp(sourced, destd)
if dir_diff.left_only or dir_diff.right_only:
    dir_diff.report_full_closure()

编辑: 这是nice blog about filecmp module

dircmp 返回的差异不准确可能有 2 个原因: 1.它使用os.stat来比较文件(浅比较),这在大多数情况下都很好,但您的要求可能会有所不同。 2. 有趣的文件 - 将文件重命名为目录等显示在 common 下。因此,您还需要考虑 dir_diff.common_funny。这是修改后的代码:

dir_diff = filecmp.dircmp(sourced, destd)
if dir_diff.left_only or dir_diff.right_only or dir_diff.common_funny:
    dir_diff.report_full_closure()

【讨论】:

  • 这是一个有趣的想法,我今天将对此进行一些测试。非常感谢您的建议!
  • 基本上,我们可以只计算一次目录差异,而不是原来情况下的两次(第一次使用 os.walk,第二次使用 filecmp.dircmp)。
  • Salil,回过头来看,如果源和目标之间的顶级文件/文件夹之一不同,这不是只执行递归比较 [report_full_closure()] 吗?
  • 我的理解是当你使用dircmp创建对象时,差异只计算一次。 left_only、right_only 和 report_full_disclosure 只是以不同的形式表示。
  • 嗨,萨利尔。有一段时间无法查看此内容,但在进行此更改后,如果顶级目录不同,脚本只会返回差异。一旦我将几个文件添加到子文件夹(从而在 sourced 和 destd 之间产生差异),脚本会将源和目标视为相同。对此有什么想法吗?也许我基本上也在实施你的建议(我的实施基本上就像你上面所说的那样)。再次感谢您的帮助!
猜你喜欢
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-19
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
  • 1970-01-01
相关资源
最近更新 更多