C# 字典的高运行时间。添加大量项

C# 字典的高运行时间。添加大量项,c#,dictionary,C#,Dictionary,我有一个C应用程序,它将文本文件中的数据存储在Dictionary对象中。要存储的数据量可能相当大,因此插入条目需要花费大量时间。对于字典中的许多项,情况变得更糟,因为存储字典数据的内部数组的大小调整了。 因此,我用将要添加的项的数量初始化了字典,但这对速度没有影响 以下是我的功能: private Dictionary<IdPair, Edge> AddEdgesToExistingNodes(HashSet<NodeConnection> connections) {

我有一个C应用程序,它将文本文件中的数据存储在Dictionary对象中。要存储的数据量可能相当大,因此插入条目需要花费大量时间。对于字典中的许多项,情况变得更糟,因为存储字典数据的内部数组的大小调整了。 因此,我用将要添加的项的数量初始化了字典,但这对速度没有影响

以下是我的功能:

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);
}