程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# PLINQ 內存列表查詢優化過程

C# PLINQ 內存列表查詢優化過程

編輯:C#入門知識

C# PLINQ 內存列表查詢優化過程。本站提示廣大學習愛好者:(C# PLINQ 內存列表查詢優化過程)文章只能為提供參考,不一定能成為您想要的結果。以下是C# PLINQ 內存列表查詢優化過程正文


產物中(基於ASP.NET MVC開辟)須要常常對藥品稱號及稱號拼音碼停止下拉婚配及成果查詢。為了加速查詢的速度,所以我最開端就將其參加內存中(年夜約有六萬五千條數據)。

上面附實體類。

public class drugInfo
{
  public int drug_nameid  { get; set; }
  public string drug_name  { get; set; }
  public string drug_search_code  { get; set; }
}

第一次做法:

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
key = key.ToLower();
var resultList = cacheList.Where(m => m.drug_name.ToLower().Contains(key) || m.drug_search_code.ToLower().Contains(key)).ToList();
stopWatch.Stop();
double eMseconds = Math.Max(0, stopWatch.Elapsed.TotalSeconds);

刷新頁面幾回,獲得個均勻用時約35MS閣下。

第二次做法:

為了削減CPU的運算,我們將LINQ表達式中的轉小寫操作優化一下,先在緩存列表上做些舉措,將稱號和搜刮碼先轉小寫存儲。

上面為改良過的實體類。

public class drugInfo
{
  public int drug_nameid  { get; set; }
  public string drug_name  { get; set; }
  public string drug_search_code  { get; set; }
  public string lower_drug_name  { get; set; }
  public string lower_drug_search_code  { get; set; }
}
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
key = key.ToLower();
var resultList = cacheList.Where(m => m.lower_drug_name.Contains(key) || m.lower_drug_search_code.Contains(key)).ToList();
stopWatch.Stop();
double eMseconds = Math.Max(0, stopWatch.Elapsed.TotalSeconds);
ViewBag.useTime = string.Format("用時{0}秒\r\n", eMseconds);

刷新頁面幾回,獲得個均勻用時約16MS閣下。

固然如許做,內存列表中會多一些冗余數據,然則獲得的機能晉升有一倍了。

第三次做法:

啟用PLINQ的並行盤算,並行盤算是NET4.0的特征,可以應用CPU多核的處置才能,進步運算效力,然則紛歧定是成倍的
LIST等泛型啟用並行盤算很簡略,應用AsParallel()便可,改良以下:

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
key = key.ToLower();
var resultList = cacheList.AsParallel().Where(m => m.lower_drug_name.Contains(key) || m.lower_drug_search_code.Contains(key)).ToList();
stopWatch.Stop();
double eMseconds = Math.Max(0, stopWatch.Elapsed.TotalSeconds);
ViewBag.useTime = string.Format("用時{0}秒\r\n", eMseconds);

異樣,我們多刷新頁面幾回,取得的均勻時光為10MS閣下。

固然,寫到這裡,年夜家認為此次的優化就停止了,至多我其時是這麼想的。
---------------------------------------------------------------------------------------------------
然則現實上,碰著了一個年夜費事。

因為產物運轉於辦事器IIS下面,應用AsParallel並行特征時(默許情形下,究竟應用若干個線程來履行PLINQ是在法式運轉時由TPL決議的。然則,假如你須要限制履行PLINQ查詢的線程數量(平日須要這麼做的緣由是有多個用戶同時應用體系,為了辦事器能同時辦事盡量多的用戶,必需限制單個用戶占用的體系資本),我們可使用ParallelEnumerable. WithDegreeOfParallelism()擴大辦法到達此目標。),客戶端一個要求就占用了過量的體系資本,招致運用法式池假逝世。沒法供給辦事。

我也測驗考試過應用WithDegreeOfParallelism設置了一個絕對較少的值,然則在應用LOADRUNNER來開啟200個並發的時刻,也會發生假逝世的情形,因而,不能不測驗考試上面第四步的方法。

第四次做法:

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
key = key.ToLower();
ConcurrentBag<drugInfo> resultList = new ConcurrentBag<drugInfo>();
Parallel.For(0, cacheList.Count, new ParallelOptions { MaxDegreeOfParallelism = 4 }, (i) =>
{
var item = cacheList[i];
if (item.lower_drug_name.Contains(key) || item.lower_drug_search_code.Contains(key))
{
resultList.Add(item);
}
});
stopWatch.Stop();
double eMseconds = Math.Max(0, stopWatch.Elapsed.TotalSeconds);
ViewBag.useTime = string.Format("用時{0}秒\r\n", eMseconds);

時光與第三步沒有甚麼差別,然則如許做處理了並發時,運用法式池假逝世的成績。至此,困擾兩天的成績完善處理,固然應用Parallel.For會帶來成果亂序的成績,然則成果數目曾經不多了,再次排序也沒有甚麼關系了。

詳細緣由拜見上面:

ParallelOptions.MaxDegreeOfParallelism指明一個並行輪回最多可使用若干個線程。TPL開端調劑履行一個並行輪回時,平日應用的是線程池中的線程,剛開端時,假如線程池中的線程很忙,那末,可認為並行輪回供給數目少一些的線程(但此數量至多為1,不然並行義務沒法履行,必需壅塞期待)。比及線程池中的線程完成了一些任務,則分派給此並行輪回的線程數量便可以增長,從而晉升全部義務完成的速度,但最多不會跨越ParallelOptions.MaxDegreeOfParallelism所指定的數量。

PLINQ的WithDegreeOfParallelism()則紛歧樣,它必需明白地指出須要應用若干個線程來完成任務。當PLINQ查詢履行時,會立時分派指定命目標線程履行查詢。

之所以PLINQ不許可靜態轉變線程的數量,是由於很多PLINQ查詢是“級聯”的,為包管獲得准確的成果,必需同步介入的多個線程。假如線程數量不定,則要完成線程同步異常艱苦。

有關C# PLINQ 內存列表查詢優化過程小編就給年夜家引見這麼多,願望對年夜家有所贊助!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved