我正在使用gawk浏览一个大型文本语料库(大约3-4 go,电子书的汇编),以便打印出至少出现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 > output
它可以很好地处理小文件(几百MB),但我无法让它处理大于1 MB的文件: gawk在不到一分钟的时间内吃光了我所有的RAM (8 MB),然后开始吃掉我的交换空间,整个系统最终冻结。
你知道我如何优化代码,即使它最终需要更长的时间吗?
非常感谢
发布于 2018-11-02 06:26:29
只要你需要将信息保存到最后,你的内存需求就是O(有序3个单词组合的数量)--大约200K words意味着8,000,000,000,000,000个组合……
即使您的图书的词汇量要小得多--比方说,只有50K个单词--仍然是50K^3或1.25*10^14。那么,即使您的awk实现每个条目只使用16字节(不可能),也仍然是2,000,000,000,000,000字节--或2000TB。
这是最坏的情况--但你看,你在玩什么数量级的游戏。
也许,您不需要对单词组合进行排序?在这种情况下,通过首先对单词进行排序,可以将数组条目的数量减少到原来的1/6。但我怀疑这对你也没什么帮助。
发布于 2019-05-21 02:51:43
您的解决方案在字符串方面效率不是很高:它为每个唯一的三元组分配一个,并且在大型语料库中,有很多这样的字符串。相反,您可以设置一个具有树索引的表并执行count[w1][w2][w3]++。这在最后需要做更多的工作,但现在每个唯一令牌只有一个字符串。
如果这还不够好,您始终可以在较小的文本组上运行代码,对输出进行排序,然后合并它们。
顺便说一句,我猜你的代码是初级的,或者你是在放弃句子结束标记之类的东西吗?
见鬼,我在回答一个6岁的问题。
https://stackoverflow.com/questions/11198316
复制相似问题