【发布时间】:2013-07-14 23:29:03
【问题描述】:
我在 C# 中有以下结构来表示图形边缘:
struct Edge
{
public Edge(int leftA, int leftB, int leftC, int leftD, int rightA, int rightB, int rightC, int rightD)
{
LeftIdA = leftA;
LeftIdB = leftB;
LeftIdC = leftC;
LeftIdD = leftD;
RightIdA = rightA;
RightIdB = rightB;
RightIdC = rightC;
RightIdD = rightD;
}
public readonly int LeftIdA;
public readonly int LeftIdB;
public readonly int LeftIdC;
public readonly int LeftIdD;
public readonly int RightIdA;
public readonly int RightIdB;
public readonly int RightIdC;
public readonly int RightIdD;
}
并且需要在 HashSet 中存储大量(大约 500 万),这样就不会出现重复。什么是 GetHashCode 的良好实现,因此它针对速度进行了优化?
我尝试将每个 id 的 4 位存储在返回的整数中,如下所示:
public override int GetHashCode()
{
int A = LeftIdA & 0xF;
int B = LeftIdB & 0xF;
int C = LeftIdC & 0xF;
int D = LeftIdD & 0xF;
int E = RightIdA & 0xF;
int F = RightIdB & 0xF;
int G = RightIdC & 0xF;
int H = RightIdD & 0xF;
int result = A;
result = (result << 4) | B;
result = (result << 4) | C;
result = (result << 4) | D;
result = (result << 4) | E;
result = (result << 4) | F;
result = (result << 4) | G;
result = (result << 4) | H;
return result;
}
但它比将项目添加到列表要慢 80%。
【问题讨论】:
-
如果你为你的数据集找到了 unique hash(你似乎有),而不是简单地将
Dictionary预增长到大量项目(即两倍你期望?),看看它是否足够快(HashSet似乎没有“预增长”方法)。 -
这种散列策略似乎不能保证唯一性,所以不适合作为字典的键。否则,我会同意。
-
@CSJ:哈希码不需要唯一。对于任何包含超过 32 位数据的数据类型,都无法创建唯一的 32 位哈希码。
-
@Guffa:确实。但是,它不能用于选择字典键,除非它的值是唯一的。这就是为什么哈希集是合适的数据结构,而不是字典。
-
@CSJ:决定唯一性的不是哈希码,而是相等比较。 HashSet 和 Dictionary 也是如此。
标签: c# performance graph hashcode