【问题标题】:IDictionary<string, string> or NameValueCollectionIDictionary<string, string> 或 NameValueCollection
【发布时间】:2010-10-11 16:09:27
【问题描述】:

我有一个场景,我可以使用 NameValueCollection 或 IDictionary。但我想知道哪一个在性能方面会更好。

-- 使用 NameValueCollection

NameValueCollection options()
{
    NameValueCollection nc = new NameValueCollection();

    nc = ....; //populate nc here

    if(sorting)
       //sort NameValueCollection nc here

    return nc;
}

-- 使用字典

IDictionary<string, string> options()
{
    Dictionary<string, string> optionDictionary = new Dictionary<string, string>();

    optionDictionary = ....; //populate

    if(sorting)
       return new SortedDictionary<string, string>(optionDictionary);
    else
       return optionDictionary;
}

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    这些集合类型不能完全互换:NameValueCollection 允许通过整数索引 进行访问。如果您不需要该功能,则不应使用NameValueCollection,因为索引不是“免费”提供的。

    根据您查看的字符串数量,我会考虑Hashtable&lt;string, string&gt;IDictionary&lt;string, string&gt;。 Krzysztof Cwalina 在这里讨论其中的微妙之处:http://blogs.gotdotnet.com/kcwalina/archive/2004/08/06/210297.aspx

    【讨论】:

    • NameValueCollection 还支持每个键有多个值(查询字符串等需要)。
    • 不正确。根据这篇关于 namevaluecollection 的 msdn 文章:msdn.microsoft.com/en-us/library/…“这种类型的集合不保留元素的顺序,并且在枚举集合时不保证特定的顺序。”
    【解决方案2】:

    IDictionary 的另一个优点是它不像 NameValueCollection 那样特定于实现。

    【讨论】:

    • “具体实现”是什么意思?
    • NameValueCollection 是一个具体类型。 IDictionary 是一个接口。因此,使用该接口,您可以拥有更大的灵活性,因为您可以使用任何实现该接口的具体类。
    【解决方案3】:

    我同意 fatcat 和 lomaxx(并且对这两个答案都投了赞成票)。我要补充一点,在选择集合类型时,集合类型的性能很可能是最后考虑的因素。使用最适合您使用需求的类型。如果您处于代码的性能关键部分(很可能不是),那么唯一的答案就是衡量每个案例 - 不要相信 Interweb,相信数字。

    【讨论】:

    • +1 表示互联网警告。这是杰克·布莱克作为亚里士多德式的方式并提倡使用琐事。
    • 真的吗?性能不是存在不同集合类型的唯一原因吗?否则我们只会使用 List 来处理所有事情。
    【解决方案4】:

    .NET 中的 NameValueCollection 基本上是 QueryStrings 用来保存键/值对的。最大的区别是添加具有相同键的两个项目时。使用 IDictionary,有两种设置值的方法。当键已经存在时,使用 .Add() 方法会在重复键上引发错误。但简单地将项目设置为一个值将覆盖该值。这就是 IDictionary 处理重复键的方式。但 NameValueCollection 将添加如下值:“value1,value2,value3”。所以现有的项目值会附加一个逗号,然后每次都附加新的值。

    在我看来,这个 NameValueCollection 是专门为 QueryString 的使用和访问而构建的。 .NET 中像 "?a=1&b=2&a=3" 这样的 QueryString 将产生 item["a"] = "1,3" 的结果。这种重复键处理方式的差异是“真正的”差异,即两者之间的最大差异。

    怀疑 NameValueCollection 在集合很大时也不使用任何哈希表来快速访问键,因为这种访问对于小型集合来说比没有哈希表时要慢。我还没有找到明确的信息来说明 NameValueCollection 是否使用哈希表来访问密钥。我确实知道 IDictionary 使用哈希表,因此访问具有许多键的 IDictionary 中的键非常快。所以我怀疑 NameValueCollection 对于小型集合来说比 IDictionary 更快。如果我的猜测是正确的,那么它意味着 NameValueCollection 绝对不能用于大型集合,因为它越大,如果没有哈希表来访问键,它就会大大减慢。

    对于查询字符串中的键数,这个数字通常非常小,所以我 NameValueCollection 确实使用散列,以获得更好的性能。但是,如果 Microsoft 设计的东西是为了性能,并为他们的用户提供最好的东西,那么 Windows 将与今天的如此不同。所以我们不能假设任何“不应该”。

    另外,我想通过对这个问题的最普遍投票的答案来澄清一个不正确的主张。 Kateroh 在错误答案下方的评论说它很好,我不需要添加任何东西。但我在这里重复 Kateroh 的评论,所以也许更多的人会意识到最受欢迎的答案是错误。 Kateroh 正确地指出:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      相关资源
      最近更新 更多