测试目标:
用两组 50000 个字符串做包含(Contains)判断,分析性能差异。
50000个字符串集合测试结果:
Dictionary/ConcurrentDictionary 能在1-2毫秒完成50000个字符串集合的包含判断;
List 需要3秒,ConcurrentBag需要 23秒!
集合类型 | 耗时(毫秒) | 耗时倍数 |
List.Contains | 3117 | 2940 |
ConcurrentBag.Contains | 22796 | 21505 |
Dictionary.ContainsKey | 1.06 | 1 |
ConcurrentDictionary.ContainsKey | 1.97 | 2 |
使用建议
- 不建议使用ConcurrentBag,不如ConcurrentDictionary<T,bool> 效率高好用;
- 频繁调用的Contains不建议使用List,会成为性能瓶颈,建议使用Dictionary或ConcurrentDictionary;
- 在多线程代码中,建议使用ConcurrentDictionary,而不是lock+Dictionary。
附测试代码一:List.Contains
public static double TestListContains()
{List<string> a = new();List<string> b = new();for(int i = 0; i < 50000; i++){a.Add(i.ToString());b.Add((50000 - i - 1).ToString());}DateTime n = DateTime.Now;foreach(var item in a){if (b.Contains(item)){}}return (DateTime.Now - n).TotalMilliseconds;
}
附测试代码二:ConcurrentBagContains
public static double TestConcurrentBagContains()
{List<string> a = new();ConcurrentBag<string> b = new();for (int i = 0; i < 50000; i++){a.Add(i.ToString());b.Add((50000 - i - 1).ToString());}DateTime n = DateTime.Now;foreach (var item in a){if (b.Contains(item)){}}return (DateTime.Now - n).TotalMilliseconds;
}
附测试代码三:DictionaryContainsKey
public static double TestDictionaryContainsKey()
{List<string> a = new();Dictionary<string,bool> b = new();for (int i = 0; i < 50000; i++){a.Add(i.ToString());b.Add((50000 - i - 1).ToString(),true);}DateTime n = DateTime.Now;foreach (var item in a){if (b.ContainsKey(item)){}}return (DateTime.Now - n).TotalMilliseconds;
}
附测试代码四:ConcurrentDictionaryContainsKey
public static double TestContains3()
{List<string> a = new();ConcurrentDictionary<string, bool> b = new();for (int i = 0; i < 50000; i++){a.Add(i.ToString());b.TryAdd((50000 - i - 1).ToString(), true);}DateTime n = DateTime.Now;foreach (var item in a){if (b.ContainsKey(item)){}}return (DateTime.Now - n).TotalMilliseconds;
}