最近在解决性能优化的问题,看到了一堆嵌套循环,四五层级的循环真的有点过分了,在数据量成万,十万级别的时候,真的非常影响性能。本文介绍了C# 减少嵌套循环的两种方法,帮助各位选择适合自己的优化方案,优化程序性能 |
当然,除了关注明显的循环例如for、foreach,还应该关注隐晦一点的循环,例如datatable.select(),linq之类的list.where、list.find等。
要优化,排除业务问题,要考虑的就是代码技术了。看到循环查找数据,尽可能向Dictionary靠拢。
eg1:一个简单的key对应一条datarow
优化前:
using System.Linq; namespace ConsoleApp1 { internal class Program { private static void Main(string[] args) { DataTable table = new DataTable(); ... for (int i = 0; i < 1000000; i++) { var row = table.AsEnumerable().FirstOrDefault(r => r["num"].ToString() == i.ToString()); ... } } } }
优化后:
using System.Data; using System.Linq; namespace ConsoleApp1 { internal class Program { private static void Main(string[] args) { DataTable table = new DataTable(); ... var dict = table.AsEnumerable().ToDictionary(r => r["num"].ToString()); for (int i = 0; i < 1000000; i++) { if (dict.ContainsKey(i.ToString())) { var row = dict[i.ToString()]; } ... } } } }
eg2:一个拼装的Key对应多条DataRow的字典
优化前:
using System.Data; using System.Linq; namespace ConsoleApp1 { internal class Program { private static void Main(string[] args) { DataTable table = new DataTable(); ... for (int i = 0; i < 1000000; i++) { var name = ""; ... var rows = table.AsEnumerable().Where(r => r["num"].ToString() == i.ToString() && r["name"].ToString() == name); } } } }
优化后:
using System.Data; using System.Linq; namespace ConsoleApp1 { internal class Program { private static void Main(string[] args) { DataTable table = new DataTable(); var group = table.AsEnumerable().GroupBy(r => GetGroupKey(r["num"].ToString(), r["name"].ToString())); var dict= group.ToDictionary(r=>r.Key); ... for (int i = 0; i < 1000000; i++) { var name = ""; var key = GetGroupKey(i.ToString(), name); if (dict.ContainsKey(key)) { var rows = dict[key]; } ... } } private static string GetGroupKey(string _num,string _name) { return $"num={_num}|name={_name}"; } } }
量变会引起质变。