问题描述
如果一个人保存一个聚合类型内的枚举,人们可能要包括该类型的哈希代码中(假设一个典型的散列函数乘)。如果一个人只是调用 SomeEnum.GetHashCode()
,现在看来,JIT盒实例,即使在发布版本。
剖析这显示了我的申请时间的10%花在拳击枚举内的各种的GetHashCode
功能。
几个值类型实施 IEquatable
或类似的接口,它允许调用的GetHashCode
作为一个静态方法;这就避免了拳击。但 System.Enum
不提供的GetHashCode
的静态超载。有计算,应使用的代码的某些手段,但能避免拳击
你可以转换为基本类型的枚举(通常 INT
除非枚举定义另有指定),并使用该类型的覆盖的GetHashCode()
方法。
枚举TestEnum
{
的Test1 ,
的Test2
}
TestEnum T = TestEnum.Test1;
((INT)T).GetHashCode(); //没有拳击
t.GetHashCode(); //拳击
下面是IL此代码:
IL_0000:NOP
IL_0001:ldc.i4.0
IL_0002:stloc.0
IL_0003: ldloc.0
IL_0004:stloc.1
IL_0005:ldloca.s V_1
IL_0007:呼叫实例INT32 [mscorlib程序] System.Int32 :: GetHashCode的()
IL_000c:$流行b $ b IL_000d:ldloc.0
IL_000e:箱ConsoleApplication1.Program / TestEnum
IL_0013:callvirt例如INT32 [mscorlib程序] System.Object的:: GetHashCode的()
IL_0018:弹出
IL_0019:RET
编辑:为了完整起见,我要指出的是, 正文int.GetHashCode()
只是返回这一点;
,从而雷蒙德陈指出,在评论上述,只需铸造枚举一个 INT
是不够好,获得的哈希码。
If one has an enumeration stored inside an aggregate type, one might want to include that inside the type's hash code (assuming a typical "multiply by primes" hash function). If one just calls SomeEnum.GetHashCode()
, it appears that the JIT boxes the instance, even in release builds.
Profiling this shows some 10% of the time of my application spent boxing enumerations inside various GetHashCode
functions.
Several value types implement IEquatable
or similar interfaces, which allows calling GetHashCode
as a static method; which avoids the boxing. But System.Enum
doesn't provide the static overload of GetHashCode
. Is there some means of computing the code that should be used but that avoids the boxing?
You could cast to the underlying type of the enum (usually int
unless the enum definition specifies otherwise) and use that type's overridden GetHashCode()
method.
enum TestEnum
{
Test1,
Test2
}
TestEnum t = TestEnum.Test1;
((int)t).GetHashCode(); // no boxing
t.GetHashCode(); // boxing
Here is the IL for this code:
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: stloc.1
IL_0005: ldloca.s V_1
IL_0007: call instance int32 [mscorlib]System.Int32::GetHashCode()
IL_000c: pop
IL_000d: ldloc.0
IL_000e: box ConsoleApplication1.Program/TestEnum
IL_0013: callvirt instance int32 [mscorlib]System.Object::GetHashCode()
IL_0018: pop
IL_0019: ret
Edit: For completeness, I should point out that the body of int.GetHashCode()
is simply return this;
, so as Raymond Chen pointed out in a comment above, simply casting the enum to an int
is good enough to obtain a hash code.
这篇关于一个人如何检索枚举的哈希码,而不拳击呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!