一个类似的问题在此处被提出,但他们没有解释为什么sort和awk之间会有速度差异。
我首先在Unix Stackexchange上提出了这个问题,但由于他们告诉我这个问题适合在Stackoverflow上发布,所以我将在这里发布它。
我需要对一个大型单词列表进行去重。我尝试了几个命令并做了一些研究这里和这里,他们解释说去重单词列表最快的方法似乎是使用awk,因为awk不排序列表。它使用哈希查找来跟踪项并删除重复项。由于AWK使用哈希查找,他们认为其大O像下面这样
List1 = 7 Mb List2 = 690 Mb
测试命令
我首先在Unix Stackexchange上提出了这个问题,但由于他们告诉我这个问题适合在Stackoverflow上发布,所以我将在这里发布它。
我需要对一个大型单词列表进行去重。我尝试了几个命令并做了一些研究这里和这里,他们解释说去重单词列表最快的方法似乎是使用awk,因为awk不排序列表。它使用哈希查找来跟踪项并删除重复项。由于AWK使用哈希查找,他们认为其大O像下面这样
然而,我发现这并不正确。这是我的测试结果。我使用这个Python脚本生成了两个随机单词列表。awk --> O(n) ?
sort --> O(n log n) ?
List1 = 7 Mb List2 = 690 Mb
测试命令
sort -u input.txt -o output.txt
awk '!x[$0]++' input.txt > output.txt
AWK结果:
List1
实际时间 0m1.643秒
用户时间 0m1.565秒
系统时间 0m0.062秒
List2
实际时间 2m6.918秒
用户时间 2m4.499秒
系统时间 0m1.345秒
SORT结果:
List1
实际时间 0m0.724秒
用户时间 0m0.666秒
系统时间 0m0.048秒
List2
实际时间 1m27.254秒
用户时间 1m25.013秒
系统时间 0m1.251秒
我一遍又一遍地进行这些测试,发现结果非常一致。也就是说,排序比AWK快得多。有人能解释为什么吗?如果有更快的方法,请说明。
************ 更新 ***********
可能影响结果的因素:
- 缓存:通过改变测试执行的顺序来排除此可能性
- 大O符号的常数因子。由于单词列表的大小(600MB),我认为它们应该变得不相关了。
- 算法的错误实现:我还没有检查过awk和sort的源代码,这仍然是一个可能性
n
是什么?如果您尝试许多不同的n
值,您是否会看到awk
的运行时间线性增加,还是sort
的增加为n lg n
? - chepnersort -u
比最坏情况下的处理更高效。使用来自500,000个不同值的1,000,000个随机值进行测试(而不是来自1,000,000个不同值的100,000,000个随机值),awk
可以快近14倍。 - chepner