最近在解決性能優化的問題,看到了一堆嵌套循環,四五層級的循環真的有點過分了,在資料量成萬,十萬級别的時候,真的非常影響性能。本文介紹了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}";
}
}
}
量變會引起質變。
本文位址:https://www.linuxprobe.com/reduce-nested-loops.html