我需要将原始键(int,也许很长)映射为高性能哈希映射数据结构中的结构值。
我的程序将包含几百个这样的映射,每个映射通常最多具有数千个条目。但是,这些地图会不断“刷新”或“搅动”;想象处理数以百万计add
和delete
消息的第二。
C或C ++中的哪些库具有适合此用例的数据结构?或者,您如何建议自己建造?谢谢!
我需要将原始键(int,也许很长)映射为高性能哈希映射数据结构中的结构值。
我的程序将包含几百个这样的映射,每个映射通常最多具有数千个条目。但是,这些地图会不断“刷新”或“搅动”;想象处理数以百万计add
和delete
消息的第二。
C或C ++中的哪些库具有适合此用例的数据结构?或者,您如何建议自己建造?谢谢!
@roe:
添加/删除操作比获取操作频繁(100倍)。
Answers:
我建议您尝试使用Google SparseHash(或C11版本的Google SparseHash-c11),看看它是否满足您的需求。它们具有内存高效的实现以及针对速度进行了优化的实现。很久以前我做了一个基准测试,就速度而言,它是最好的哈希表实现(但是有缺点)。
C或C ++中的哪些库具有适合此用例的数据结构?或者,您如何建议自己建造?谢谢!
查看LGPL的Judy阵列。从未使用过自己,但有几次向我做广告。
您也可以尝试对STL容器进行基准测试(std :: hash_map等)。取决于平台/实现和源代码调整(尽可能多地预分配动态内存管理非常昂贵),它们可能会具有足够的性能。
另外,如果最终解决方案的性能胜过解决方案的成本,则可以尝试订购具有足够RAM的系统,以将所有内容放入普通阵列。按索引访问的性能无与伦比。
添加/删除操作比获取操作频繁(100x)。
这表明您可能想先集中精力改进算法。如果只写数据而不读数据,那为什么还要写数据呢?
如果您有多线程程序,则可以在intel线程构建块库中找到一些有用的哈希表。例如,tbb :: concurrent_unordered_map具有与std :: unordered_map相同的api,但是它的主要功能是线程安全的。
来自android来源(因此Apache 2许可)
https://github.com/CyanogenMod/android_system_core/tree/ics/libcutils
看一下hashmap.c,选择include / cutils / hashmap.h,如果不需要线程安全,则可以删除互斥代码,libcutils / str_parms.c中有一个示例实现。
首先检查现有的解决方案(如libmemcache)是否适合您的需求。
如果不 ...
哈希图似乎是您要求的肯定答案。它基于键提供o(1)查找。如今,大多数STL库都提供某种哈希。因此,请使用您的平台提供的一种。
完成该部分后,您必须测试解决方案,以查看默认哈希算法是否足以满足您的需求。
如果不是,您应该探索网上找到的一些很好的快速哈希算法
如果这还不够好,您可以自己滚动一个哈希模块,以解决您通过测试的STL容器以及上述哈希算法之一看到的问题。确保将结果发布到某处。
哦,它有多个映射,这很有趣...也许可以通过将密钥作为64位num来进行简化,其高位用于区分它属于哪个映射,并将所有密钥值对添加到一个巨型哈希中。我已经看到有数十万个符号的散列在基本质数散列算法上运行得很好。
您可以检查与数百张地图相比该解决方案的性能..我认为从内存配置文件的角度来看可能会更好...如果需要进行此练习,请务必将结果张贴在某处
我相信,除了哈希算法之外,它还可以是不断增加/删除内存(可以避免吗?)和cpu缓存使用情况配置文件,这些配置文件对于应用程序的性能可能更为关键。
祝好运
http://incise.org/hash-table-benchmarks.html gcc具有非常好的实现。但是,请记住,它必须遵守一个非常糟糕的标准决定:
如果进行了重新哈希处理,则所有迭代器均无效,但是对单个元素的引用和指针仍然有效。如果没有发生实际的重新哈希处理,则不会进行任何更改。
http://www.cplusplus.com/reference/unordered_map/unordered_map/rehash/
这意味着基本上该标准说该实现必须基于链接列表。它会阻止具有更好性能的开放式寻址。
我认为google sparse使用的是开放式寻址,尽管在这些基准测试中,只有密集版本的性能优于竞争对手。但是,稀疏版本优于所有在内存使用方面的竞争。(它也没有任何平稳的纯线性wrt元素数)