【问题标题】:Best Collection for Fast String Lookup快速字符串查找的最佳集合
【发布时间】:2011-07-28 17:20:20
【问题描述】:

我需要一个字符串列表和一种快速确定字符串是否包含在该列表中的方法。

为了提高查找速度,我考虑了SortedListDictionary;但是,当我只需要一个 string 时,两者都可以使用 KeyValuePairs。

我知道我可以使用 KeyValuePair 并简单地忽略 Value 部分。但我更喜欢高效,只是想知道是否有更适合我要求的集合。

【问题讨论】:

    标签: c# .net collections


    【解决方案1】:

    如果您使用 .NET 3.5 或更高版本,请使用 HashSet<String>

    如果您有很多条目,Dictionary<string, byte>(或您想要的 TValue 类型参数的任何类型)将比 SortedList 更快 - 后者将使用二进制搜索,所以它'将是 O(log n) 查找,而不是 O(1)。

    【讨论】:

    • @Jonathan:同意——这就是生活。在 .NET 4 中,有一个表示集合的接口 (ISet<T>) 以及 SortedSet<T> 中的另一个选项(在这种情况下也不是特别有用)。
    • 我只是在回顾这个。 O(1) 查找确实很快。但是,我猜这个集合实现了某种散列。那么 O(1) 不是假设没有碰撞吗? (顺便说一句,我正在研究你的书。)
    • @Jonathan:如果哈希值合理,则为 O(1),因此不会有 太多 次冲突。
    【解决方案2】:

    如果您只想知道字符串是否在集合中,请使用HashSet<string>

    【讨论】:

      【解决方案3】:

      HashSet<string> 类似于 Dictionary,但只有键。

      【讨论】:

        【解决方案4】:

        如果您想滚动自己的数据结构,请使用 Trie。 http://en.wikipedia.org/wiki/Trie

        最坏的情况是如果字符串存在:O(字符串长度)

        【讨论】:

          【解决方案5】:

          这听起来像是一份工作

           var keys = new HashSet<string>();
          

          根据MSDN:包含函数具有 O(1) 复杂度。

          但您应该知道,添加时不会出现重复错误。

          【讨论】:

          • 更准确地说,Add 方法不会抛出异常,但如果添加了键,则返回 true,如果键已经存在,则返回 false。
          【解决方案6】:

          我知道这个答案对这个聚会来说有点晚了,但我遇到了一个问题,我们的系统运行缓慢。在分析之后,我们发现在我们构建数据结构的方式中发生了很多字符串查找。

          所以我们做了一些研究,came across these benchmarks,做了我们自己的测试,现在已经切换到使用 SortedList。

          if (sortedlist.ContainsKey(thekey))
          {   
          //found it.
          }
          

          尽管字典被证明更快,但我们需要重构的代码更少,性能提升对我们来说已经足够了。

          无论如何,想分享该网站以防其他人遇到类似问题。他们在您要查找的字符串是“键”(如 HashTable、字典等)或“值”(列表、数组或字典等)的数据结构之间进行比较,这就是我们所在的位置存储。

          【讨论】:

            【解决方案7】:

            我知道这个问题已经过时了,但我只需要解决同样的问题,只针对非常小的字符串集(2 到 4 之间)。

            在我的例子中,我实际上对字符串数组使用了手动查找,结果比HashSet&lt;string&gt;(我对其进行了基准测试)快得多。

            for (int i = 0; i < this.propertiesToIgnore.Length; i++)
            {
                if (this.propertiesToIgnore[i].Equals(propertyName))
                {
                    return true;
                }
            }
            

            注意,它比仅用于小数组的哈希集更好!

            编辑:仅适用于手动 for 循环,不使用 LINQ,cmets 中的详细信息

            【讨论】:

            • 是的,HashSet&lt;&gt; 有一些开销。我只会在搜索更大的集合时推荐它。顺便说一句,您的代码可以缩短为 return PropertiesToIgnore.Any(p =&gt; p.Equals(propertyName))
            • 不幸的是,使用 Linq 会使执行速度减慢 10 倍!基准测试结果ArrayManualLoop: 6.018 nsArrayLinq: 59.171 ns。 Linq 刺破了处理器缓存,所有可能的收益都失去了。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-02
            • 2020-12-09
            • 1970-01-01
            • 1970-01-01
            • 2010-11-20
            • 1970-01-01
            相关资源
            最近更新 更多