今天我们来比较一下集合检索方法性能更优问题,测试代码
public class Entity{public int Id { get; set; }public int No { get; set; }public string Col1 { get; set; }public string Col2 { get; set; }public string Col3 { get; set; }public string Col4 { get; set; }public string Col5 { get; set; }public string Col6 { get; set; }public string Col7 { get; set; }public string Col8 { get; set; }public string Col9 { get; set; }public string Col10 { get; set; }}static void TestFindVelocity(int totalDataCount, int executeCount){#region 构造数据List<Entity> datas = new List<Entity>();for (int i = 0; i < totalDataCount; i++){var item = new Entity{No = i + 1,Col1 = Guid.NewGuid().ToString(\"N\"),Col2 = Guid.NewGuid().ToString(\"N\"),Col3 = Guid.NewGuid().ToString(\"N\"),Col4 = Guid.NewGuid().ToString(\"N\"),Col5 = Guid.NewGuid().ToString(\"N\"),Col6 = Guid.NewGuid().ToString(\"N\"),Col7 = Guid.NewGuid().ToString(\"N\"),Col8 = Guid.NewGuid().ToString(\"N\"),Col9 = Guid.NewGuid().ToString(\"N\"),Col10 = Guid.NewGuid().ToString(\"N\"),};datas.Add(item);}#endregionvar dicDatas = datas.ToDictionary(x => x.No);var hashSetDatas = datas.ConvertAll<Tuple<int, int>>(x => new Tuple<int, int>(x.No, x.No + 1000)).ToHashSet();Stopwatch sw = new Stopwatch();Random random = new Random();Entity searchResult = null;bool searchResultBool = false;// 每次查询索引List<int> indexs = Enumerable.Range(1, executeCount).Select(x => random.Next(1, totalDataCount)).ToList();sw.Start();for (int i = 0; i < executeCount; i++){searchResult = datas.FirstOrDefault(x => x.No == indexs[i]);}sw.Stop();Console.WriteLine($\"list FirstOrDefault 耗时:{sw.ElapsedMilliseconds}\");sw.Restart();for (int i = 0; i < executeCount; i++){searchResult = datas.Where(x => x.No == indexs[i]).First();}sw.Stop();Console.WriteLine($\"list Where+First 耗时:{sw.ElapsedMilliseconds}\");sw.Restart();for (int i = 0; i < executeCount; i++){searchResultBool = datas.Exists(x => x.No == indexs[i]);}sw.Stop();Console.WriteLine($\"list Exist 耗时:{sw.ElapsedMilliseconds}\");sw.Restart();for (int i = 0; i < executeCount; i++){searchResult = datas.Find(x => x.No == indexs[i]);}sw.Stop();Console.WriteLine($\"list Find 耗时:{sw.ElapsedMilliseconds}\");sw.Restart();for (int i = 0; i < executeCount; i++){dicDatas.TryGetValue(indexs[i], out searchResult);}sw.Stop();Console.WriteLine($\"dictionary TryGetValue 耗时:{sw.ElapsedMilliseconds}\");sw.Restart();for (int i = 0; i < executeCount; i++){searchResultBool = hashSetDatas.Contains(new Tuple<int, int>(indexs[i], indexs[i] + 1000));}sw.Stop();Console.WriteLine($\"Hashset contains 耗时:{sw.ElapsedMilliseconds}\");}
结果
(集合数量,测试次数) | Linq.FirstOrDefault | Linq.Where+First |
List.Exists |
List.Find |
Dictionary.TryGetValue |
HashSet.Contains |
(100,5000000) |
4544 | 3521 | 1992 | 1872 | 66 | 924 |
(1000,5000000) |
41751 | 29417 | 20631 | 19490 | 70 | 869 |
(10000,5000000) |
466918 | 397425 | 276409 | 281647 | 85 | 946 |
(50000,5000) |
6292 | 4602 | 4252 | 3559 | 0 | 2 |
(500000,5000) |
56988 | 55568 | 48423 | 48395 | 1 | 5 |