C# · 12月 28, 2021

C#字典内存管理

我有一个字典< string,int>这有可能包含超过1000万个独特的键.我正在努力减少这个占用的内存量,同时仍然保持字典的功能.

我的想法是将字符串的哈希存储为一个长的代码,这会将应用程序内存使用量减少到可接受的数量(约1.5 gig〜〜.5 gig),但我对我的做法不太了解这个.

long longKey=BitConverter.ToInt64(cryptoTransformSHA1.ComputeHash(enc.GetBytes(strKey)),0);

基本上这样做会使SHA1哈希结束,并将其中的第一个块放入一个很长的时间,然后我将其用作键.尽管如此,至少对于我正在测试的数据,我不觉得这是一个非常可靠的解决方案,因为密钥冲突的可能性增加.

有没有其他方法可以减少字典的内存占用空间,还是我以上的方法不像我想像的那样可怕?

[编辑]
为了澄清,我需要保持使用字符串查找Dictionary中包含的值的能力.将实际的字符串存储在字典中会占用大量内存.我想要做的是使用字典< long,int>其中long是字符串散列函数的结果.

解决方法 所以我最近做了类似的事情,而且由于我的应用程序相当独特的一些原因,没有使用数据库.其实我是试图停止使用一个数据库.我发现GetHashCode在3.5中得到了显着改善.一个重要的注意事项,绝对不要从GetHashCode存储结果.永远不能.它们不能保证在框架版本之间保持一致.

所以你真的需要对你的数据进行分析,因为不同的哈希函数在你的数据上可能会更好或更好.你也需要考虑速度.作为一般规则,加密哈希函数不应该有许多冲突,即使哈希的数量进入数十亿.对于我需要独特的东西,我通常使用SHA1 Managed.一般来说,CryptoAPI具有可怕的性能,即使底层哈希函数表现良好.

对于64位哈希,我目前使用的是Lookup3和FNV1,它们都是32位哈希值.为了发生碰撞,两者都需要进行碰撞,数学上是不可能的,我没有看到发生在大约1亿个哈希.您可以在网络上公开查找代码.

仍然进行自己的分析.对我有用的工作可能不适合你.实际上在我办公室里,不同应用程序的不同需求实际上使用了不同的哈希函数或哈希函数的组合.

我会避免任何未经证实的哈希函数.与认为应该编写它们的人有一样多的哈希函数.做你的研究和测试测试测试.