C#4词典或哈希表可以包含的项目数量的实际限制是多少,这些结构可以合理包含的字节总数。我将处理大量对象,并想知道这些结构何时开始遇到问题。
对于上下文,我将使用具有大量内存的64位系统。另外,我将需要使用某种形式或“键”来查找对象。鉴于性能需求,这些对象将需要驻留在内存中,并且许多对象将长期存在。
尽管我需要避免使用第三方或开放源代码库,但还是可以建议其他方法/模式。出于规范原因,我需要能够使用本机C#(或C ++ \ CLI)来构建它。
C#4词典或哈希表可以包含的项目数量的实际限制是多少,这些结构可以合理包含的字节总数。我将处理大量对象,并想知道这些结构何时开始遇到问题。
对于上下文,我将使用具有大量内存的64位系统。另外,我将需要使用某种形式或“键”来查找对象。鉴于性能需求,这些对象将需要驻留在内存中,并且许多对象将长期存在。
尽管我需要避免使用第三方或开放源代码库,但还是可以建议其他方法/模式。出于规范原因,我需要能够使用本机C#(或C ++ \ CLI)来构建它。
Answers:
要指出的一件事是,词典将不会保存对象本身(可能会占用较大的内存),而只会保留对对象的引用,因此,如果对象很复杂,则不会影响词典的大小。
我已经在字典中的内存中收集了数千个项目,问题不是字典的大小,而是内存中对象本身的大小。在这些情况下,字典本身只是所涉及内存的一小部分。
对于大型词典,要考虑的一件事是手动配置和管理词典容量。在正常情况下,.Net可以解决这个问题(在当前实现中,如果它用完了空间,它将调整为素数,该素数至少是Dictionary当前大小的两倍)。但是,如果您知道要创建一个大型词典或要扩展词典而不是.Net为您猜测和调整词典的大小(这是相对昂贵的),则最好自己动手(一定要在初始时大小,并可能在以后调整大小)。如果您对字典的容量应有合理的启发,可以通过管理字典的容量来完成此操作。Microsoft建议在MSDN在对Dictionary对象的评论中。但是,似乎不确定这种方法的真正价值,尽管我不确定该测试的严格程度以及当字典调整大小非常快时.Net平台是否进行了其他优化。
这是关于对象和内存大小的有用的堆栈溢出问题。
我最近更新了github项目hash-table-shootout(在这里:https : //github.com/jimbelton/hash-table-shootout)。标准的gcc无序映射大约有1.8 GB的开销来存储40M对象。对我来说,这似乎很糟糕,但是即使是性能最佳的内存,Google sparse_hash_map也会占用600 MB的空间,使用它会导致性能损失。如果要提高速度,在所包含的算法中,Glib GHashTable是最快的,并且具有良好的内存性能(大约1.3 GB的开销)。基准测试结果发布在这里:https : //jimbelton.wordpress.com/2015/07/01/hash-table-shootout-on-github/