作者:Devil灬旋律 | 来源:互联网 | 2023-02-10 13:16
我有一个760万行的文件。每行的形式为:A,B,C,D,其中B,C,D是用于计算A的重要性级别的值,A是每行唯一的字符串标识符。我的方法:
private void read(String filename) throws Throwable {
BufferedReader br = new BufferedReader(new FileReader(filename));
Map mmap = new HashMap<>(10000000,0.8f);
String line;
long t0 = System.currentTimeMillis();
while ((line = br.readLine()) != null) {
split(line);
mmap.put(splitted[0], 0.0);
}
long t1 = System.currentTimeMillis();
br.close();
System.out.println("Completed in " + (t1 - t0)/1000.0 + " seconds");
}
private void split(String line) {
int idxComma, idxToken = 0, fromIndex = 0;
while ((idxComma = line.indexOf(delimiter, fromIndex)) != -1) {
splitted[idxToken++] = line.substring(fromIndex, idxComma);
fromIndex = idxComma + 1;
}
splitted[idxToken] = line.substring(fromIndex);
}
其中插入了虚拟值0.0以进行“概要分析”,并拆分了为该类定义的简单String数组。我最初使用String的split()方法,但发现上述方法更快。
当我运行上面的代码时,花12秒钟来解析文件,这比我认为的要多。例如,如果我用字符串向量替换HashMap并仅从每一行中获取第一个条目(即,我没有在其中添加关联的值,因为它应该摊销常量),所以整个文件的读取时间少于3秒
这向我表明(i)HashMap中存在很多冲突(我已尝试通过预先分配大小并相应地设置负载因子来最大程度地减少调整大小的次数),或(ii)hashCode()函数某种程度上很慢。我对此表示怀疑(ii),因为如果我使用HashSet,则可以在4秒内读取文件。
我的问题是:HashMap执行如此缓慢的原因可能是什么?hashCode()是否不足以容纳这种大小的地图,或者从根本上讲我忽略了某些东西?