diff 消耗大量内存和 CPU

diff 消耗大量内存和 CPU

我有两个文件,全部.txt(525,953,272 条记录)和子集.txt(525,298,281 条记录)。每条记录只不过是一个 17 位 ASCII 整数。两个文件均已排序,并且每个文件中的重复记录已被删除。中的每个值子集.txt也存在于全部.txt。我希望找到以下记录全部.txt那些不在子集.txt

我正在尝试diff在这两个文件之间运行 a ,认为它会写出其中的行全部.txt但不在子集.txt。该机有64GB内存。已经diff运行了半个小时,目前已经获取了75%左右的内存。

任何人都可以推测可能会发生什么,以及是否有论据diff可能有帮助?这不是我diff想要做的吗?我应该使用不同的方法吗?

答案1

任何人都可以推测可能会发生什么,以及 diff 是否有可能有帮助的论点?这不是 diff 的本意吗?我应该使用不同的方法吗?

这不是diff本意要做的事;当输入已排序(如您所见)后,该作业的工具是comm

$ seq 10 15 > subset.txt
$ seq 10 20 > all.txt
$ comm -13 subset.txt all.txt
16
17
18
19
20

选项comm有点不寻常,因为它们会转动离开输出。第 1 列包含文件 1 特有的行;第 2 列包含文件 2 特有的行;第 3 列的行是两者“共有”的。通过使用选项,-13我们要求 comm 向我们显示仅在“all.txt”中的行。

答案2

diff可能不是最合适的工具。我会尝试编写一个简单的脚本来专门执行您想要的操作。

一切都在记忆中

这是一个非常简单且通用的解决方案。它将两个文件加载到最小的内存结构中,subset.txt从 的记录中减去 的记录all.txt并写出余数。

#!/usr/bin/env python

with open('diff.txt', 'w') as diff:

    for record in set(open('all.txt', 'r')) - set(open('subset.txt', 'r')):
        diff.write(record)

将其保存到类似 的文件中create_diff.py,然后chmod +x create_diff.py在两个文件所在的目录中运行它。

内存中唯一的子集

如果您需要进一步优化以降低内存占用量,也可以在不将整个文件加载到内存中的情况下实现这一点,特别是all.txt不需要完全加载到内存中,而只需迭代一次。

#!/usr/bin/env python

subset_txt = open('subset.txt', 'r')
subset = subset_txt.readlines()
subset_txt.close()

with open('diff.txt', 'w') as diff_txt:
    with open('all.txt', 'r') as all_txt:
        for line in all_txt:
            if line not in subset:
                diff_txt.write(line)

基于输入/输出

这应该是最慢的变体,因为它严重依赖 I/O,但它的内存占用量较低,因为它不需要将整个文件加载到内存中。无论您的文件是否已排序/唯一,它都有效。

#!/usr/bin/env python

diff_txt = open('diff.txt', 'w')

with open('all.txt', 'r') as all_txt:
    with open('subset.txt', 'r') as subset_txt:
        for all_line in all_txt:
            found = False

            for sub_line in subset_txt:
                if all_line == sub_line:
                    found = True
                    break

            if found is False:
                diff_txt.write(all_line)
                subset_txt.seek(0)

diff_txt.close()

仅适用于无重复的排序文件<- 根据您的情况推荐

如果您确定两个文件都已排序并且不包含重复项,这应该是最好的解决方案。这两个文件都只读取一次,不需要完全加载到内存中。

#!/usr/bin/env python

diff_txt = open('diff.txt', 'w')

with open('all.txt', 'r') as all_txt:
    with open('subset.txt', 'r') as subset_txt:
        subset_line = subset_txt.readline()

        for all_line in all_txt:
            if all_line == subset_line:
                subset_line = subset_txt.readline()
            else:
                diff_txt.write(all_line)

diff_txt.close()

相关内容