将项添加到ASP.NET Dictionary类的方法更有效?

时间:2012-04-08 23:11:37

标签: c# asp.net performance dictionary

我正在使用C#在ASP.NET中将逗号分隔的字符串列表转换为字典(省略任何重复项):

string str = "1,2, 4, 2, 4, item 3,item2, item 3"; //Just a random string for the sake of this example

我想知道哪种方法更有效率?

1 - 使用try / catch块:

Dictionary<string, string> dic = new Dictionary<string, string>();

string[] strs = str.Split(',');
foreach (string s in strs)
{
    if (!string.IsNullOrWhiteSpace(s))
    {
        try
        {
            string s2 = s.Trim();
            dic.Add(s2, s2);
        }
        catch
        {
        }
    }
}

2 - 或者使用ContainsKey()方法:

string[] strs = str.Split(',');
foreach (string s in strs)
{
    if (!string.IsNullOrWhiteSpace(s))
    {
        string s2 = s.Trim();
        if (!dic.ContainsKey(s2))
            dic.Add(s2, s2);
    }
}

编辑。谢谢大家的参与!

一个非常有趣的发现。如果你看看下面的dtb提供的答案,他提出了两种使用hashSet的方法。我会在这里配音:

方法1:

var hashSet = new HashSet<string>(from s in str.Split(',')
                           where !string.IsNullOrWhiteSpace(s)
                           select s.Trim()); 

方法2:

var hashSet = new HashSet<string>();
foreach (string s in str.Split(','))
{
     if (!string.IsNullOrWhiteSpace(s))
     {
         hashSet.Add(s.Trim());
     }
}

我问他哪种方法的性能更快,而且有趣的是,方法2更快。以下是使用Stopwatch类通过在循环中运行发布版本中的每个方法1,000,000次来完成的时间:

Method 1: 1,440 ms average
Method 2: 1,124 ms average

5 个答案:

答案 0 :(得分:6)

如果您需要一套而不是字典,我建议您使用HashSet<T> Class

  

的HashSet&LT; T&GT;类

     

表示一组值。

     

集合是一个不包含重复元素的集合,其元素没有特定的顺序。


var hashSet = new HashSet<string>(from s in str.Split(',')
                                  where !string.IsNullOrWhiteSpace(s)
                                  select s.Trim());

或同样

var hashSet = new HashSet<string>();
foreach (string s in str.Split(','))
{
    if (!string.IsNullOrWhiteSpace(s))
    {
        hashSet.Add(s.Trim());
    }
}

答案 1 :(得分:3)

看起来你不需要字典:一个简单的LINQ表达式应该给你一个没有重复项的列表:

var res = str
    .Split(',')
    .Where(s => !string.IsNullOrWhitespace(s))
    .Select(s => s.Trim())
    .Distinct()
    .ToList();

如果您坚持使用字典,则可以改为使用ToDictionary

var res = str
    .Split(',')
    .Where(s => !string.IsNullOrWhitespace(s))
    .Select(s => s.Trim())
    .Distinct()
    .ToDictionary(s=>s, s=>s);

强烈建议不要在正常的程序流程中使用try/catch,因为它隐藏了你的意图:C#中的异常是为异常情况保留的,而不是你能用{{1}安全陷阱的常规事物条件。

答案 2 :(得分:2)

使用.ContainsKey的方法2更多是语义,并且最有可能比抑制异常更有效。

答案 3 :(得分:2)

使用异常来控制预期的执行流程通常是不受欢迎的,捕获异常是很昂贵的,所以我选择v2。如果它对您真的很重要,为什么不设置基准?我猜2“效率更高”,但你可以很容易地证实这一点。

答案 4 :(得分:1)

如果您没有使用字典中的值,则可以改为使用HashSet<string>,并且向哈希集添加项会自动删除重复项:

HashSet<string> set = new HashSet<string>(
  str.Split(',')
  .Select(s => s.Trim())
  .Where(s => s.Length > 0)
);