gpt4 book ai didi

java - 我使用 Java HashMap 越多,性能下降得越多 - 即使大小稳定

转载 作者:行者123 更新时间:2023-12-01 19:13:55 28 4
gpt4 key购买 nike

我想扫描大量文本并计算词频(n-gram 频率实际上对于那些熟悉 NLP/IR 的人来说)。我为此使用 Java HashMap。所以发生的事情是我逐行处理文本。对于每一行,我提取单词,对于每个单词,我更新 HashMap 中相应的频率。

问题是这个过程变得越来越慢。例如,它一开始每秒处理大约 100k 行,然后性能立即开始下降。在大约 2800 万行之后,性能已下降至 16k 行/秒 - 当然,还会继续下降。

首先想到的是,这是由于 hashmap 中的条目太多造成的,这导致每次 put 和 get 的速度每次都变慢。所以我尝试的是在任何时候只保留 HashMap 中最频繁的条目(比如 100k)。这是通过使用第二个映射将频率映射到单词来完成的(如下所示:Automatically sorted by values map in Java)

总体来说,这执行得更快。 (虽然一开始是 56k 行/秒,但到了 2800 万行时,性能只下降到了 36.5k 行/秒)。然而,这个数字也在持续下降,但速度要慢得多 - 但事实仍然是,它一直在下降。

当 HashMap 的大小保持不变时,您对为什么会发生这种情况有任何可能的解释吗?您认为这与垃圾收集器有什么关系吗?意思是,我不断向散列映射中放入和删除对象的事实会导致内存碎片或其他什么?或者可能是哈希函数问题?由于我使用的是字符串,因此哈希函数是 Java 的默认字符串哈希函数。

这是执行上述任务的代码部分:

http://pastebin.com/P8S6Sj86

注意:我是 Java 新手,因此非常欢迎您对答案进行任何详细说明

最佳答案

我建议使用 Java VisualVM 进行一些分析。这是 Java 附带的 - 转到命令行并输入 jvisualvm 来运行它。这样可以很容易地看出内存扰动是否是您的问题,或者特定类型的对象是否被创建了数十万次。

如果您将代码分解为多个方法,您还可以判断哪些方法运行时间过长。

我确实注意到您在内部循环中不必要地创建了大量对象。这肯定不会提高性能,尽管它可能不是罪魁祸首。

例如:

float avg = new Float(sumItems) / new Float (freqMap.size());

应该是

float avg = (float)sumItems / freqMap.size();

另一段可能很麻烦的代码是:

System.out.println(numItems + " items counted");

根据您的操作系统或 IDE,将 100,000 行写入控制台需要大量时间。相反,只需为每 1000 个项目编写一个进度更新即可。

关于java - 我使用 Java HashMap 越多,性能下降得越多 - 即使大小稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7475547/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com