使用org.javatuples.Pair和HashMap创建密集矩阵太慢
我有一个大小约为30000x30000的密集对称矩阵,它包含字符串之间的距离。由于距离是对称的,因此矩阵的上三角形存储在表单的一个以制表符分隔的3列文件中使用org.javatuples.Pair和HashMap创建密集矩阵太慢,java,matrix,hashmap,collision,Java,Matrix,Hashmap,Collision,我有一个大小约为30000x30000的密集对称矩阵,它包含字符串之间的距离。由于距离是对称的,因此矩阵的上三角形存储在表单的一个以制表符分隔的3列文件中 stringA<tab>stringB<tab>distance data.txt非常大(~4亿行),而且过程最终会减慢到爬行,大部分时间都花在java.util.HashMap.put上 我不认为对上应该有(m)任何哈希代码冲突,但我可能错了。我如何验证这一点?只要看看p12.hashCode()和p12.hash
stringA<tab>stringB<tab>distance
data.txt
非常大(~4亿行),而且过程最终会减慢到爬行,大部分时间都花在java.util.HashMap.put
上
我不认为对上应该有(m)任何哈希代码冲突,但我可能错了。我如何验证这一点?只要看看p12.hashCode()和p12.hashCode()的独特性就足够了吗
如果没有碰撞,还有什么会导致减速
有没有更好的方法来构造这个矩阵以便快速查找?我现在正在使用
表
,因为我也意识到我的字符串是唯一的,我可以使用它们的散列,而不是字符串本身作为键,以减少内存需求。表的创建在合理的时间内运行,但是,序列化和反序列化结果对象时存在问题:即使从String
移动到Integer
,我也遇到了内存不足的错误。在我决定不同时存储a-b
和b-a
对之后,它似乎起到了作用,但我可能在我的机器能够处理的边缘上取得了平衡。你最好还是自己写一对吧。另外,使用手动split
而不是String.split
@LouisWasserman您是指org.javatuples.Pair
中的hashCode
实现吗?感谢split
的建议,尽管根据profileries,现在它只占处理时间的0.5%,这就是我所说的实现;它甚至不适用于有两个元素的情况。我想这里的主要瓶颈是文件I/O。您是否测量了只读取文件而不使用它的时间?@radoh file I/O不是问题所在。正如Louis在上面指出的,问题在于对的hashCode()
,它确实会对我的数据产生大量冲突。我现在正在试验一种替代方案,如果可行的话,我会发布它
import org.javatuples.Pair;
HashMap<Pair<String,String>,Double> pairScores = new HashMap<Pair<String,String>,Double>();
BufferedReader bufferedReader = new BufferedReader(new FileReader("data.txt"));
String line = null;
while((line = bufferedReader.readLine()) != null) {
String [] parts = line.split("\t");
String d1 = parts[0];
String d2 = parts[1];
Double score = Double.parseDouble(parts[2]);
Pair<String,String> p12 = new Pair<String,String>(d1,d2);
Pair<String,String> p21 = new Pair<String,String>(d2,d1);
pairScores.put(p12, score);
pairScores.put(p21, score);
}