问题描述
我有一个大的字典,其中最关键的是小数,但System.Decimal的GetHash code()是disasterously坏。为了证明我的猜测,我跑了一个for循环100.000 neigboring小数,并检查了分布。使用100.000不同的十进制数只有2个(二!!!)不同的hash codeS。
十进制重新psented为16字节$ P $。就像的Guid!但是的Guid的GetHash code()分布是pretty的好。 我怎么能转换成十进制来的Guid在C#尽可能便宜?不安全code是OK!
编辑:请求,所以这里的测试是code:
十进制D =96000000000000000000米;
字典< INT,INT> hashcount =新字典< INT,INT>();
INT长度= 100000;
的for(int i = 0; I<长度;我++)
{
INT散列code = d.GetHash code();
INT N;
如果(hashcount.TryGetValue(哈希code,出N))
{
hashcount [散列code = N + 1;
}
其他
{
hashcount.Add(哈希code,1);
}
ð++;
}
Console.WriteLine(hashcount.Count);
这将打印7.我不记得了小数点开始给了我2。
EXTREMELY哈克解决方案(但可能是最快的)
公共静态类utils的
{
[StructLayout(LayoutKind.Explicit)
结构DecimalGuidConverter
{
[FieldOffset(0)]
公共十进制小数;
[FieldOffset(0)]
公众的Guid的Guid;
}
私有静态DecimalGuidConverter _CONVERTER;
公共静态的Guid DecimalToGuid(十进制DEC)
{
_converter.Decimal =分解;
返回_converter.Guid;
}
公共静态十进制GuidToDecimal(GUID GUID)
{
_converter.Guid = GUID;
返回_converter.Decimal;
}
}
//打印000e0000-0000-0000-8324-6ae7b91d0100
Console.WriteLine(Utils.DecimalToGuid((十进制)Math.PI));
//打印00000000-0000-0000-1821-000000000000
Console.WriteLine(Utils.DecimalToGuid(8472米));
//打印8472
Console.WriteLine(Utils.GuidToDecimal(Guid.Parse(00000000-0000-0000-1821-000000000000)));
I have a big dictionary where the key is decimal, but the GetHashCode() of System.Decimal is disasterously bad. To prove my guess, I ran a for loop with 100.000 neigboring decimals and checked the distribution. 100.000 different decimal numbers used only 2 (two!!!) different hashcodes.
Decimal is represented as 16 bytes. Just like Guid! But the GetHashCode() distribution of Guid is pretty good. How can I convert a decimal to Guid in C# as cheap as possible?Unsafe code is OK!
EDIT: The test was requested, so here is the code:
decimal d = 96000000000000000000m;
Dictionary<int, int> hashcount = new Dictionary<int, int>();
int length = 100000;
for (int i = 0; i < length; i++)
{
int hashcode = d.GetHashCode();
int n;
if (hashcount.TryGetValue(hashcode, out n))
{
hashcount[hashcode] = n + 1;
}
else
{
hashcount.Add(hashcode, 1);
}
d++;
}
Console.WriteLine(hashcount.Count);
This prints 7. I do not remember the starting decimal that gave me 2.
EXTREMELY HACKY SOLUTION (but probably fastest possible)
public static class Utils
{
[StructLayout(LayoutKind.Explicit)]
struct DecimalGuidConverter
{
[FieldOffset(0)]
public decimal Decimal;
[FieldOffset(0)]
public Guid Guid;
}
private static DecimalGuidConverter _converter;
public static Guid DecimalToGuid(decimal dec)
{
_converter.Decimal = dec;
return _converter.Guid;
}
public static decimal GuidToDecimal(Guid guid)
{
_converter.Guid = guid;
return _converter.Decimal;
}
}
// Prints 000e0000-0000-0000-8324-6ae7b91d0100
Console.WriteLine(Utils.DecimalToGuid((decimal) Math.PI));
// Prints 00000000-0000-0000-1821-000000000000
Console.WriteLine(Utils.DecimalToGuid(8472m));
// Prints 8472
Console.WriteLine(Utils.GuidToDecimal(Guid.Parse("00000000-0000-0000-1821-000000000000")));
这篇关于转换System.Decimal到的System.Guid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!