删除大单词列表中重复项的最快方法?


14

我需要对大型单词表进行重复数据删除。我尝试了几个命令,并在此处此处进行了一些研究,他们解释说,最快的重复数据删除单词列表的方法似乎是使用awk。

awk-> O(n)吗?排序-> O(n log n)?

但是我发现这似乎是不正确的。这是我的测试结果:

sort -u input.txt -o output.txt 

真实的0m12.446s
用户0m11.347s
sys 0m0.906s

awk '!x[$0]++' input.txt > output.txt

真实的0m47.221s
用户0m45.419s
sys 0m1.260s

因此,使用sort -u快3.7倍。为什么是这样?有没有更快的方法来进行重复数据删除?

***********更新********

正如有人在评论中指出的那样,可能是我的词表已在某种程度上被排序。为了排除这种可能性,我使用此python脚本生成了两个单词表。

列表1 = 7 Mb
列表2 = 690 Mb

结果AWK:
List1
实数0m1.643s
用户0m1.565s
sys 0m0.062s

List2
实际2m6.918s
用户2m4.499s
sys 0m1.345s

结果排序:
List1
实数0m0.724s
用户0m0.666s
sys 0m0.048s

List2
实际1m27.254s
用户1m25.013s
sys 0m1.251s


可能是您的输入数据已经排序?
iruvar

我将生成一个带有数字的随机列表,并进行检查以确保
karlpy

2
大O表示法是关于输入长度接近无穷大时会发生的情况:它告诉您一个算法可以随着大输入进行缩放。一些算法在较小的输入大小时效果更好。
ctrl-alt-delor

1
Karlpy,您是先执行哪个命令,还是先执行awk排序?由于文件缓存,这可能会有所不同
iruvar

1
@karlpy:“我更改了文件名...”如果您是说您已重命名了文件,那还不够。重命名文件只是将新名称与旧的索引节点相关联,而旧的索引节点仍指向相同的旧数据块。如果它们被缓存,它们仍然被缓存。根据ISTM,更好的技术是(1)复制文件,然后(2)在一个文件上运行一个命令,(3)在另一个文件上运行另一个命令。
斯科特

Answers:


3

您是在问一个错误的问题,还是在一个错误的堆栈中提出了错误的问题,这是一个更好的问题,可在编程/堆栈溢出中让人们根据awk和sort中使用的算法为您提供答案。

PS:还可以通过nawk,mawk和gawk进行必要的操作,以向我们提供更多“区域划分”的细节;)并以最小,最大,平均和标准偏差分别进行100次运行。

无论是从CompSci 210还是手头的问题,都与所使用的算法有关。排序使用了几种,具体取决于大小和内存限制,一旦内存不足,排序就会将文件保存到磁盘中的临时文件中以进行合并排序,因此您必须查看源代码以了解什么特定sort(1)命令在您正在其上运行的特定OS上使用,但是根据经验,它会尽可能多地加载到内存中,对其进行一些快速排序,写出到磁盘,重复冲洗,然后在最后,它将对小的排序文件进行合并排序。因此,这里您将获得零件的O(n * log2(N)),然后进行近似O(n * log(n))合并操作

awk:x [$ 0] ++机制是“假设”使用哈希的。但是散列的问题(假设为O(1)“查找”操作)是冲突以及冲突的处理。当数据不能很好地散布,不填充存储桶等时,这可能会导致问题。在大列表中,如果冲突处理不正确,则哈希可能是一个大内存问题(并且您可能需要调整用于所需数据的哈希算法),然后您需要查看实际哈希函数的性能,然后O(1)可能更接近插入的O(log(n))(即O (1)对于第一次搜索,如果不存在,则将其添加为O(log(n))),然后n * O(1)变为an * O(log(n))= > O(n * log(n)),更不用说您也在以“解释的”方式来做事:)


-2

速度差异是因为“ sort”是命令(链接),而“ awk”是编程语言(链接)。

'sort'命令接受输入并返回输出。而“ awk”是一种编程语言,它首先解释代码(终端命令),然后开始对其进行处理。就那么简单。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.