3

我正在使用 gawk 浏览一个大型文本语料库(大约 3-4GB,电子书汇编),以便打印出至少出现 3 次的 3 个单词的每个关联,以生成语言统计数据。这是代码:

file.awk 的内容:

BEGIN { RS="[^[:alnum:]]+" } 

{ w1 = w2; w2 = w3; w3 = $0 } 

NR > 2 { count[tolower(w1 " " w2 " " w3)]++ } 

END { 
     for (phrase in count) {
         if (count[phrase] >= 3) { 
             print phrase, count[phrase] 
         } 
     } 
} 

命令:gawk -f file.awk mytxtfile > 输出

它适用于小文件(几百 MB),但我无法让它适用于大于 1GB 的文件:gawk 在不到一分钟的时间内吃掉我所有的 RAM(8GB),然后开始吃掉我的交换和整个系统最终冻结。

你知道我如何优化代码,即使最终需要更长的时间吗?

非常感谢

4

2 回答 2

0

您的解决方案在字符串方面效率不高:它为每个唯一的三元组分配一个,并且在大型语料库中,它们有很多。相反,您可以设置一个带有树索引的表并执行count[w1][w2][w3]++. 最后需要做更多的工作,但现在每个唯一标记只有一个字符串。

如果这还不够好,您始终可以在较小的文本组上运行代码,对输出进行排序,然后合并它们。

顺便说一句,我猜你的代码是基本的,或者你是否在前面提到句尾标记之类的东西?

妈的,我在回答一个6岁的问题。

于 2019-05-20T18:51:43.493 回答
0

只要您需要将信息保留到最后,您的记忆需求就是 O(有序3 词组合的数量)——大约200K 词意味着 8,000,000,000,000,000 个组合......

即使你的书的组合词汇量要小得多——比如说,只有 50K 词——那仍然是 50K^3 或 1.25*10^14。然后,即使您的 awk 实现每个条目仅使用 16 个字节(不可能),这仍然是 2,000,000,000,000,000 字节 - 或 2000TB。

这是最坏的情况——但你看,你在玩什么数量级。

也许,您不需要订购单词组合?在这种情况下,您可以通过首先对单词进行排序来将数组条目的数量减少 6 倍。但我怀疑,这对你也有帮助......

于 2018-11-01T22:26:28.843 回答