我需要一种能够非常快速地处理小集(10-20个字符串,最多50个,不同长度)的数据结构。误报是可以的,但假阴性则不然。
最后一项要求使得布隆过滤器看起来很合适,但我不确定它们的速度,还有其他建议吗?
编辑:该集只需要支持插入+成员资格测试。
答案 0 :(得分:4)
使用for-loop而不是使用String.Equals
检查成员身份的字符串数组怎么样?
对于这些小的,花哨的数据结构可能会产生太多的开销,并且大哦不适用。您是否尝试过做最简单的事情并测量它?
(如果误报是好的,你也可以保留例如1024个bool的数组,你可以通过查看前两个字符的最低5位来计算一个糟糕的'散列'字符串,给你一个10位指向布尔数组的索引。似乎这只是一些指令。)
答案 1 :(得分:1)
根据您希望针对该集执行的操作,最快可能是HashSet<string>
。有关详情,请参阅HashSet。
<强> ADDITION 强>
问谷歌先生,这是一篇写一篇Bloom Filter function in C#的绅士写的文章。但是,他仍然使用(多个)哈希码来填充过滤器。我希望在小数据集上它会慢于HashSet
。
答案 2 :(得分:1)
如果要检查成员资格的字符串集远远大于有效字符串集,那么Trie可能会为您提供比HashSet更好的性能。散列集中查找的速度取决于散列算法的运行时间,散列算法通常为O(k),其中k是字符串的长度。无论字符串是否在哈希集中,都是如此。
使用Trie,查找仍然是O(k),但如果字符串不在Trie中,它将在单个字符不匹配时立即终止查找。最好的情况是,查找无效字符串是O(1)。
答案 3 :(得分:0)
查看MSDN上的System.Collections.Specialized Namespace。
特别是HybridDictionary和StringDictionary。
我知道它们不是集合,但您可以为每个键使用空值。 (Java在开箱即用的Set中也是如此,但仍然是“快速”。
答案 4 :(得分:0)
为什么不使用Radix Tree?它是一个基于trie的专用set数据结构,用于存储一组字符串。
答案 5 :(得分:0)
如果HashSet对你来说太慢,你可以使用经典的LZ压缩器技术:固定大小的哈希码数组,其中每个条目都指向链接的字符串列表。
如果您知道数据的域只是构造理想的哈希函数并使用它。 如果不是你的情况你可以使用类似Murmur hash之类的string.GetHashCode() 并使用hash(str)%array.Length作为数组的索引。
我认为数组大小为256-512个条目,足以满足50个字符串的数据结构。
答案 6 :(得分:0)
布隆过滤器对散列表的主要好处是它们的大小取决于数据库中的对象数量和允许的误报概率,但不取决于对象本身的大小。由于您的数据库非常小,我怀疑它的大小是您主要关注的问题。
HashSets 理论上是满足您需求的最佳数据结构,但由于数据库太小,因此像SortedDictionary这样的O(log(n))结构通常更可取,或者甚至可能只是线性搜索(如上所述)。我记得从基于散列的集合切换到基于树的集合的故事大大提高了小集的性能。
最好的方法是在它们之间切换并比较每种的性能。