我遇到了这个问题:我正在阅读900个文件,在处理完文件后,我的最终输出将是HashMap<String, <HashMap<String, Double>>
。第一个字符串是fileName,第二个字符串是word,double是字频。处理顺序如下:
我正在使用字符串BufferedReader
。问题是,在处理完第一个文件之后,Hash变得如此之大,以至于一段时间后性能非常低。我想听听这方面的解决方案。我的想法是在限制达到存储到文件后创建一个有限的哈希。这样做直到处理完所有内容,最后混合所有哈希值。
答案 0 :(得分:1)
为什么不一次只读一个文件,并将该文件的结果转储到磁盘,然后读取下一个文件等?显然,每个文件在映射方面都独立于其他文件,那么为什么要在编写第二个文件时保留第一个文件的结果呢?
您可以将每个文件的结果写入另一个文件(例如foo.txt =&gt; foo.txt.map),或者您可以在结果之间创建一个带有某种分隔符的单个文件,例如
==== foo.txt ====
word - 1
the - 3
get - 3
==== bar.txt ====
apple - 2
// etc
顺便问一下,为什么你使用double
作为频率?当然它应该是一个整数值......
答案 1 :(得分:1)
哈希映射处理的时间不应随着增长而显着增加。由于散列函数不合适或填充太多,您的地图可能会出现偏差。除非你使用的内存比你从系统中获得的内存多,否则你不必分手。
当我在内存中运行包含大量对象的大型哈希映射(或任何集合)时,我所看到的是VM试图运行垃圾收集器时疯狂。它达到了这样的程度,即90%的时间用于JVM开始垃圾收集器,这需要一段时间,并且发现几乎每个对象都有一个引用。
我建议分析你的应用程序,如果它是垃圾收集器,那么增加堆空间并调整垃圾收集器。此外,如果您可以近似所需的哈希映射大小并提供足够大的分配(请参阅构造函数中的initialCapacity和loadFactor选项),它将会有所帮助。
答案 2 :(得分:0)
您可以尝试使用此库来提高性能。
http://high-scale-lib.sourceforge.net/
它类似于java集合api,但是性能很高。如果您可以在小批量处理这些结果后批量处理并合并这些结果,那将是理想的选择。
这篇文章将帮助您提供更多输入。
答案 3 :(得分:0)
我想重新考虑你的问题:
因为您正在尝试构建倒排索引:
使用Multimap而不是Map<String, Map<String, Integer>>
Multimap<word, frequency, fileName, .some thing else tomorrow>
现在,读取一个文件,构建Multimap并将其保存在磁盘上。 (类似于Jon的回答)
阅读x文件后,将所有Multimaps合并在一起:putAll(multimap)
如果您确实需要一个包含所有值的公共地图。
答案 4 :(得分:0)
为什么不使用自定义类
public class CustomData {
private String word;
private double frequency;
//Setters and Getters
}
并将您的地图用作
Map<fileName, List<CustomData>>
这样至少你的地图上只有900个键。
-Ivar