我想扫描大量文本并计算词频(n-gram 频率实际上适用于那些熟悉 NLP/IR 的人)。我为此使用了 Java HashMap。所以会发生什么是我逐行处理文本。对于每一行,我提取单词,对于每个单词,我更新哈希图中的相应频率。
问题是这个过程变得越来越慢。例如,它首先处理大约 100k 行/秒 - 性能立即开始下降。在大约 2800 万行之后,性能已经下降到 16k 行/秒——当然还在不断下降。
首先想到的是,这是由于 hashmap 中的条目过多造成的,这导致每次 put 和 get 每次都变慢。所以我尝试的是在任何时候只在哈希图中保留最频繁的条目(比如 100k)。这是通过使用将频率映射到单词的第二个映射来完成的(如这里:Automatically sorted by values map in Java)
一般来说,这执行得更快。(虽然开始时为 56,000 行/秒,但当达到 2800 万行时,性能仅下降到 36.5k 行/秒)。然而,这也一直在以更慢的速度下降——但事实仍然是,它一直在下降。
当哈希图的大小保持不变时,您是否有任何可能的解释为什么会发生这种情况?您认为这与垃圾收集器有关吗?意思是,我不断向/从哈希映射中放置和删除对象的事实会碎片化内存或其他东西?还是可能是散列函数问题?由于我使用的是字符串,因此散列函数是 Java 对字符串的默认散列函数。
这是执行上述任务的代码部分:
注意:我是一名 Java 新手,因此您的答案中的任何详细说明都非常受欢迎