我在Golang中遇到问题,我需要能够查找大约5,000,000个字符串的字符串键,每个字符串只包含a-z(小写)和0-9个字符。与uint32和uint64类似的问题作为键。
地图(哈希表)非常适合这种情况,但它使用的内存太多了。
对于这类事情必须有已知的方法,我一直在研究B-Tree,但我不确定它是否是最有效的机制。
我的问题的一些特殊性可以导致更有效的解决方案:
因为它只需要只读,所以在我看来,将它作为带有一系列索引的预排序列表,可能会很好。我一开始以为我可能只能在每个级别(即字符)中使用36(26个字母+10个数字)索引进行切片...但当然这意味着36 ^无论哪个最终与...相反高效。然后我想也许我可以为每个级别只放一个36的索引,但最后我需要交叉加载数组/切片以获得结果的ID。
我想我正在寻找某种非常具体的B-Tree实现,但更多地关注我的目的(没有B。)
有人知道我建议存在的任何事情吗?
答案 0 :(得分:1)
我试试Compressed Trie。这是在具有词典键的场景中完全可用的数据结构。 B树主要用于外部记忆,因为它们最小化树的深度。特里或更高效的内存散列是正确的方法。
答案 1 :(得分:1)
我认为这取决于你想要最终实现的目标。例如:
如果问题1的答案是(a)那么trie可能是数据结构的一个很好的选择。如果问题1的答案是(b)那么你可能最好使用bitset或bloom过滤器。在这两个中,布隆过滤器将是最快和最大的内存效率,但是是概率性的,并且会产生一些误报(但没有真正的否定),根据您对问题2的回答,这可能适用于您的用例,也可能不适用。 / p>
答案 2 :(得分:0)
如果您知道要使用多少个字符串并且只需要检查它们的存在,那么优化地图和内存使用的另一个想法。
map[string]struct{}
,struct{}
保证大小为0,与使用至少1个字节的bool不同。if _, ok := m[key]; ok { ... }
Compressed Tries很好,但是除非你非常紧迫地记忆,map[string]struct{}
会更快。
答案 3 :(得分:0)
您应该使用Trie数据结构,该结构旨在非常有效地将字符串映射到值。有关详细信息,请参阅https://en.wikipedia.org/wiki/Trie。
上可以找到作为英国政府新网站一部分的大量使用的Go。