最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# PLINQ 內(nèi)存列表查詢優(yōu)化歷程

 更新時(shí)間:2016年03月24日 08:57:29   作者:qwsf01115  
這篇文章主要介紹了C# PLINQ 內(nèi)存列表查詢優(yōu)化歷程的相關(guān)資料,需要的朋友可以參考下

產(chǎn)品中(基于ASP.NET MVC開發(fā))需要經(jīng)常對藥品名稱及名稱拼音碼進(jìn)行下拉匹配及結(jié)果查詢。為了加快查詢的速度,所以我最開始就將其加入內(nèi)存中(大約有六萬五千條數(shù)據(jù))。

下面附實(shí)體類。

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);

刷新頁面幾次,得到個(gè)平均用時(shí)約35MS左右。

第二次做法:

為了減少CPU的運(yùn)算,我們將LINQ表達(dá)式中的轉(zhuǎn)小寫操作優(yōu)化一下,先在緩存列表上做些動作,將名稱和搜索碼先轉(zhuǎn)小寫存儲。

下面為改進(jìn)過的實(shí)體類。

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("用時(shí){0}秒\r\n", eMseconds);

刷新頁面幾次,得到個(gè)平均用時(shí)約16MS左右。

雖然這樣做,內(nèi)存列表中會多一些冗余數(shù)據(jù),但是得到的性能提升有一倍了。

第三次做法:

啟用PLINQ的并行計(jì)算,并行計(jì)算是NET4.0的特性,可以利用CPU多核的處理能力,提高運(yùn)算效率,但是不一定是成倍的
LIST等泛型啟用并行計(jì)算很簡單,使用AsParallel()即可,改進(jìn)如下:

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("用時(shí){0}秒\r\n", eMseconds);

同樣,我們多刷新頁面幾次,獲得的平均時(shí)間為10MS左右。

當(dāng)然,寫到這里,大家以為這次的優(yōu)化就結(jié)束了,至少我當(dāng)時(shí)是這么想的。
---------------------------------------------------------------------------------------------------
但是事實(shí)上,碰到了一個(gè)大麻煩。

由于產(chǎn)品運(yùn)行于服務(wù)器IIS上面,使用AsParallel并行特性時(shí)(默認(rèn)情況下,到底使用多少個(gè)線程來執(zhí)行PLINQ是在程序運(yùn)行時(shí)由TPL決定的。但是,如果你需要限制執(zhí)行PLINQ查詢的線程數(shù)目(通常需要這么做的原因是有多個(gè)用戶同時(shí)使用系統(tǒng),為了服務(wù)器能同時(shí)服務(wù)盡可能多的用戶,必須限制單個(gè)用戶占用的系統(tǒng)資源),我們可以使用ParallelEnumerable. WithDegreeOfParallelism()擴(kuò)展方法達(dá)到此目的。),客戶端一個(gè)請求就占用了過多的系統(tǒng)資源,導(dǎo)致應(yīng)用程序池假死。無法提供服務(wù)。

我也嘗試過使用WithDegreeOfParallelism設(shè)置了一個(gè)相對較少的值,但是在使用LOADRUNNER來開啟200個(gè)并發(fā)的時(shí)候,也會產(chǎn)生假死的情況,于是,不得不嘗試下面第四步的辦法。

第四次做法:

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("用時(shí){0}秒\r\n", eMseconds);

時(shí)間與第三步?jīng)]有什么區(qū)別,但是這樣做解決了并發(fā)時(shí),應(yīng)用程序池假死的問題。至此,困擾兩天的問題完美解決,雖然使用Parallel.For會帶來結(jié)果亂序的問題,但是結(jié)果數(shù)量已經(jīng)不多了,再次排序也沒有什么關(guān)系了。

具體原因參見下面:

ParallelOptions.MaxDegreeOfParallelism指明一個(gè)并行循環(huán)最多可以使用多少個(gè)線程。TPL開始調(diào)度執(zhí)行一個(gè)并行循環(huán)時(shí),通常使用的是線程池中的線程,剛開始時(shí),如果線程池中的線程很忙,那么,可以為并行循環(huán)提供數(shù)量少一些的線程(但此數(shù)目至少為1,否則并行任務(wù)無法執(zhí)行,必須阻塞等待)。等到線程池中的線程完成了一些工作,則分配給此并行循環(huán)的線程數(shù)目就可以增加,從而提升整個(gè)任務(wù)完成的速度,但最多不會超過ParallelOptions.MaxDegreeOfParallelism所指定的數(shù)目。

PLINQ的WithDegreeOfParallelism()則不一樣,它必須明確地指出需要使用多少個(gè)線程來完成工作。當(dāng)PLINQ查詢執(zhí)行時(shí),會馬上分配指定數(shù)目的線程執(zhí)行查詢。

之所以PLINQ不允許動態(tài)改變線程的數(shù)目,是因?yàn)樵S多PLINQ查詢是“級聯(lián)”的,為保證得到正確的結(jié)果,必須同步參與的多個(gè)線程。如果線程數(shù)目不定,則要實(shí)現(xiàn)線程同步非常困難。

有關(guān)C# PLINQ 內(nèi)存列表查詢優(yōu)化歷程小編就給大家介紹這么多,希望對大家有所幫助!

相關(guān)文章

  • c#訪問this關(guān)鍵字和base關(guān)鍵字示例

    c#訪問this關(guān)鍵字和base關(guān)鍵字示例

    this關(guān)鍵字引用類的當(dāng)前實(shí)例。靜態(tài)成員方法中不能使用this關(guān)鍵字,this關(guān)鍵字只能在實(shí)例構(gòu)造函數(shù)、實(shí)例方法或?qū)嵗L問器中使用。base關(guān)鍵字用于從派生類中訪問基類的成員。下面學(xué)習(xí)一下這二個(gè)關(guān)鍵字的使用方法
    2014-01-01
  • 深入理解C#表達(dá)式樹的使用

    深入理解C#表達(dá)式樹的使用

    表達(dá)式樹是C#編程語言中一個(gè)強(qiáng)大的特性,本文將深入探討表達(dá)式樹的基本概念、創(chuàng)建方法、節(jié)點(diǎn)類型、遍歷技巧以及在C#中的應(yīng)用示例,感興趣的可以了解一下
    2024-03-03
  • C#使用foreach語句遍歷集合類型的方法

    C#使用foreach語句遍歷集合類型的方法

    這篇文章主要介紹了C#使用foreach語句遍歷集合類型的方法,可實(shí)現(xiàn)通過foreach語句遍歷集合類的功能,需要的朋友可以參考下
    2015-06-06
  • C# NetRemoting實(shí)現(xiàn)雙向通信

    C# NetRemoting實(shí)現(xiàn)雙向通信

    本篇文章主要介紹了C# NetRemoting實(shí)現(xiàn)雙向通信,.Net Remoting 是由客戶端通過Remoting,訪問通道以獲得服務(wù)端對象,再通過代理解析為客戶端對象來實(shí)現(xiàn)通信的
    2017-03-03
  • c# Thread類線程常用操作詳解

    c# Thread類線程常用操作詳解

    這篇文章主要介紹了c# Thread類線程常用操作詳解的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-03-03
  • C#中Ilist與list的區(qū)別小結(jié)

    C#中Ilist與list的區(qū)別小結(jié)

    本篇文章主要是對C#中Ilist與list的區(qū)別進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • C#實(shí)現(xiàn)Excel轉(zhuǎn)PDF時(shí)設(shè)置內(nèi)容適應(yīng)頁面寬度

    C#實(shí)現(xiàn)Excel轉(zhuǎn)PDF時(shí)設(shè)置內(nèi)容適應(yīng)頁面寬度

    將Excel轉(zhuǎn)為PDF格式時(shí),通常情況下轉(zhuǎn)換出來的PDF頁面都是默認(rèn)的寬度大小。所以本文提供了C#實(shí)現(xiàn)Excel轉(zhuǎn)PDF時(shí)設(shè)置內(nèi)容適應(yīng)頁面寬度的示例代碼,需要的可以參考一下
    2022-04-04
  • C#面向?qū)ο缶幊讨氯螒驅(qū)崿F(xiàn)方法

    C#面向?qū)ο缶幊讨氯螒驅(qū)崿F(xiàn)方法

    這篇文章主要介紹了C#面向?qū)ο缶幊讨氯螒驅(qū)崿F(xiàn)方法,以一個(gè)完整的猜拳游戲?yàn)槔v述了C#面向?qū)ο蟪绦蛟O(shè)計(jì)的具體實(shí)現(xiàn)步驟,具有一定的學(xué)習(xí)與借鑒價(jià)值,需要的朋友可以參考下
    2014-11-11
  • C#生成影像金字塔的原理實(shí)例

    C#生成影像金字塔的原理實(shí)例

    最近在處理一個(gè)關(guān)于影像金字塔的問題,這個(gè)金字塔程序是用C#寫的,需要的朋友可以參考一下
    2013-05-05
  • 關(guān)于C#執(zhí)行順序帶來的一些潛在問題

    關(guān)于C#執(zhí)行順序帶來的一些潛在問題

    這篇文章主要給大家介紹了關(guān)于C#執(zhí)行順序帶來的一些潛在問題,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評論

云林县| 嵊州市| 泰安市| 巴东县| 京山县| 班戈县| 荣昌县| 万安县| 沽源县| 台江县| 武鸣县| 抚州市| 合阳县| 西乌珠穆沁旗| 阿拉善盟| 江川县| 剑阁县| 高密市| 策勒县| 寻乌县| 贵定县| 辽阳市| 平果县| 克东县| 新宁县| 咸阳市| 右玉县| 遂平县| 平罗县| 隆林| 即墨市| 三原县| 贺兰县| 尚义县| 固镇县| 淅川县| 蓝山县| 宁乡县| 桐柏县| 揭东县| 元谋县|