C# 字典的高运行时间。添加大量项
我有一个C应用程序,它将文本文件中的数据存储在Dictionary对象中。要存储的数据量可能相当大,因此插入条目需要花费大量时间。对于字典中的许多项,情况变得更糟,因为存储字典数据的内部数组的大小调整了。 因此,我用将要添加的项的数量初始化了字典,但这对速度没有影响 以下是我的功能:C# 字典的高运行时间。添加大量项,c#,dictionary,C#,Dictionary,我有一个C应用程序,它将文本文件中的数据存储在Dictionary对象中。要存储的数据量可能相当大,因此插入条目需要花费大量时间。对于字典中的许多项,情况变得更糟,因为存储字典数据的内部数组的大小调整了。 因此,我用将要添加的项的数量初始化了字典,但这对速度没有影响 以下是我的功能: private Dictionary<IdPair, Edge> AddEdgesToExistingNodes(HashSet<NodeConnection> connections) {
private Dictionary<IdPair, Edge> AddEdgesToExistingNodes(HashSet<NodeConnection> connections)
{
Dictionary<IdPair, Edge> resultSet = new Dictionary<IdPair, Edge>(connections.Count);
foreach (NodeConnection con in connections)
{
...
resultSet.Add(nodeIdPair, newEdge);
}
return resultSet;
}
IdPair
是一个struct
,并且您没有重写Equals
或GetHashCode
。这意味着将使用这些方法的默认实现
对于值类型,Equals
和GetHashCode
的默认实现使用反射,这可能导致性能低下。尝试提供您自己的方法实现,看看这是否有帮助
我建议的实现可能并不完全符合您的需要:
public struct IdPair : IEquatable<IdPair>
{
// ...
public override bool Equals(object obj)
{
if (obj is IdPair)
return Equals((IdPair)obj);
return false;
}
public bool Equals(IdPair other)
{
return id1.Equals(other.id1)
&& id2.Equals(other.id2);
}
public override int GetHashCode()
{
unchecked
{
int hash = 269;
hash = (hash * 19) + id1.GetHashCode();
hash = (hash * 19) + id2.GetHashCode();
return hash;
}
}
}
public结构IdPair:IEquatable
{
// ...
公共覆盖布尔等于(对象对象对象)
{
如果(obj是IdPair)
返回等于((IdPair)obj);
返回false;
}
公共布尔等于(IdPair其他)
{
返回id1.Equals(其他.id1)
&&id2.等于(其他id2);
}
公共覆盖int GetHashCode()
{
未经检查
{
int hash=269;
hash=(hash*19)+id1.GetHashCode();
hash=(hash*19)+id2.GetHashCode();
返回散列;
}
}
}
因为您有一个struct,所以得到了Equals()和GetHashCode()的默认实现。正如其他人指出的,这不是很有效,因为它使用反射,但我认为反射不是问题所在
我的猜测是,默认的GetHashCode()会使散列代码分布不均匀,例如,如果默认实现返回所有成员的简单XOR(在这种情况下,散列(a,b)=散列(b,a))。我找不到任何关于ValueType.GetHashCode()如何实现的文档,但请尝试添加
public override int GetHashCode() {
return oneId << 16 | (anotherId & 0xffff);
}
public override int GetHashCode(){
return oneId您是否在IdPair
类中重写Equals
和GetHashCode
?如果是,您的GetHashCode
算法是否产生了合适的散列分布?IdPair只是一个带构造函数的结构。我将其添加到了问题中完美的猜测!您的小hashfunction缩短了操作时间每次添加平均约0.02毫秒。非常感谢,Luke。(标准)hashfunction就是问题所在。使用您的解决方案,我将每次添加的操作时间平均缩短到~0.03毫秒。这比erikkallens解决方案慢了一点,但比以前好了很多。值得注意的是,事先设置字典的大小似乎根本没有(时间)效果。
public override int GetHashCode() {
return oneId << 16 | (anotherId & 0xffff);
}