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

C#函數(shù)式編程中的緩存技術(shù)詳解

 更新時(shí)間:2015年01月28日 10:42:30   投稿:junjie  
這篇文章主要介紹了C#函數(shù)式編程中的緩存技術(shù)詳解,本文我們將分成兩部分來講解,第一部分為預(yù)計(jì)算,第二部分則為緩存,需要的朋友可以參考下

緩存技術(shù)

      該節(jié)我們將分成兩部分來講解,第一部分為預(yù)計(jì)算,第二部分則為緩存。緩存這個(gè)技術(shù)對(duì)應(yīng)從事開發(fā)的人員來說是非常熟悉的,從頁面緩存到數(shù)據(jù)庫緩存無處不在,而其最重要的特點(diǎn)就是在第一次查詢后將數(shù)據(jù)緩存,在以后的查詢過程中就無需重新計(jì)算而直接從內(nèi)存中將結(jié)果返回,大大提高了性能,而我們這里的緩存則集中運(yùn)用在函數(shù)上。

 預(yù)計(jì)算

      可能一些人并不能立馬理解這個(gè)詞的含義,所以我們就簡(jiǎn)單的從生活例子出發(fā)介紹一下。很多人在工作中一定會(huì)這樣做事,比如上級(jí)吩咐了你一件事,但是這件事的后半部分要等另一個(gè)同事做好之后把對(duì)應(yīng)的材料給你你才能完成。但是我們不可能一直等到那個(gè)同事完成了把材料交給我們,我們才去做這件事。而是會(huì)將這件事的前半部分做好,那么剩下的只要那個(gè)同事完成并交給我們,我們就直接完成下半部分就可以了。同理這樣的思維也可以用在軟件開發(fā)中,比如下面這個(gè)函數(shù):

      函數(shù)內(nèi)部是利用a的值計(jì)算出c,最后再將c和b相加得出最后的結(jié)果。當(dāng)然這個(gè)例子并不能完整的體現(xiàn)預(yù)計(jì)算的特點(diǎn),但能夠讓我們理解預(yù)計(jì)算是如何實(shí)現(xiàn)的。假設(shè)這里的

是一個(gè)耗時(shí)操作,并且實(shí)際使用中會(huì)出現(xiàn)a的值不變動(dòng),但是b的值會(huì)經(jīng)常變動(dòng)的情況,但是每次調(diào)用這個(gè)函數(shù)都會(huì)重新根據(jù)a計(jì)算出c,那么我們就需要一定的方式改變這個(gè)格局,這里我們可以先嘗試采用部分應(yīng)用(這里介紹一個(gè)函數(shù)式開發(fā)的庫->PortableFCSLib,可以在NuGet中安裝或者到他的github網(wǎng)站上下載:https://github.com/rmoritz/PortableFCSLib):

這里我們的意圖是只會(huì)計(jì)算一次C的值,而不是兩次,然后我們看看最終的輸出結(jié)果:

      還是計(jì)算了兩次的C,理由很簡(jiǎn)單,因?yàn)椴糠謶?yīng)用僅僅只是利用閉包將參數(shù)保存了起來,只有所有參數(shù)傳遞完成后才會(huì)調(diào)用這個(gè)函數(shù),并達(dá)不到預(yù)計(jì)算的效果,所以我們就需要新的方式來完成,下面我們修改DoSomeThing函數(shù):

      這里我們可以看到參數(shù)只剩下了a,而返回值則變成了函數(shù),這樣才執(zhí)行第一次這個(gè)方法之后將會(huì)計(jì)算出c值,由于閉包的緣故c的值就會(huì)被保存。下面我們來看一看如何調(diào)用:

最后看看是不是只計(jì)算了一次C的值:

      這樣我們就大功告成了,當(dāng)然筆者在這里還要再提一下,這些例子僅僅只是為了讀者能夠快速的理解,在實(shí)際的運(yùn)用中還要讀者能夠根據(jù)情況靈活多變,比如這個(gè)函數(shù)接收三個(gè)參數(shù),但是前兩個(gè)不經(jīng)常變動(dòng),但是第三個(gè)卻經(jīng)常變動(dòng),并且函數(shù)的內(nèi)部是根據(jù)前兩個(gè)參數(shù)計(jì)算得出一個(gè)結(jié)果,而返回值需要根據(jù)第三個(gè)參數(shù)和這個(gè)計(jì)算后的值得出,那么我們就可以返回但一個(gè)參數(shù)的函數(shù),而函數(shù)本身需要接收兩個(gè)。

 緩存

      利用該技術(shù)之前我們需要理解幾個(gè)名詞,就是引用透明函數(shù)純度。這兩者都是指在我們調(diào)用一個(gè)函數(shù)時(shí),無論任何時(shí)候,只要傳遞的參數(shù)一致,返回的結(jié)果都應(yīng)該是一致的。這樣的函數(shù)我們才能夠利用緩存。首先我們先定義一個(gè)函數(shù),而這個(gè)函數(shù)將會(huì)是我們后面需要緩存的函數(shù):

然后我們修改函數(shù)使之能夠進(jìn)行緩存:

      這里我們可以看到我們利用了字典來對(duì)這個(gè)函數(shù)進(jìn)行了緩存。函數(shù)首先從字典中判斷是否存在參數(shù)a的key,如果存在直接返回計(jì)算后的結(jié)果,如果不存在則計(jì)算該結(jié)果,并保存到字段中,這樣我們就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的緩存。下面我們來看看最終的結(jié)果,是不是確實(shí)使用了緩存:

      當(dāng)傳遞參數(shù)10的時(shí)候,因?yàn)榫彺嬷袥]有所以進(jìn)行了緩存,參數(shù)5也是一樣,而下一行再次計(jì)算10的時(shí)候就沒有進(jìn)行計(jì)算而是直接從字典中返回了對(duì)應(yīng)的結(jié)果。但是上面這種方式還存在一個(gè)問題,如果存在多個(gè)函數(shù)都需要緩存,則這個(gè)類會(huì)存在多個(gè)字段類型的字段(一些人可能會(huì)問為什么不能共享一個(gè)字典,這樣你就要在key的命名上花費(fèi)一定的功夫,而且很容易造成重復(fù)),那么我們就需要一種能夠不污染類的方式來進(jìn)行緩存,這里我們先介紹如何使用FCSLib中的Memoizer實(shí)現(xiàn)內(nèi)部緩存:

      這里我們可以看到Memoizer公開了一個(gè)GetMemory的靜態(tài)方式用來獲取對(duì)應(yīng)的緩存對(duì)象,然后利用這個(gè)返回的對(duì)象我們就可以進(jìn)行緩存,最終的效果跟之前的是一樣的,我們可以看看最后控制臺(tái)輸出的結(jié)果:

 如果你不知道該為這個(gè)函數(shù)起什么名字,我們可以利用反射來獲取這個(gè)函數(shù)的全稱,比如下面這個(gè)修改之后的DoSomeThing函數(shù)就是利用了這個(gè)方式:

當(dāng)然除了手動(dòng)修改函數(shù)的方式,我們也可以采用自動(dòng)化來使沒有利用緩存的函數(shù)使用緩存技術(shù),下面我們來寫一個(gè)函數(shù)來實(shí)現(xiàn)這個(gè)功能:

      我們可以看到紅色框住的部分,其實(shí)就是利用了閉包,在這個(gè)函數(shù)之上又嵌套了一層函數(shù),這樣我們就能夠進(jìn)行緩存了,只有在緩存中不存在時(shí)才調(diào)用函數(shù)求值,但是面對(duì)多個(gè)參數(shù)的情況,上面這些無法正常緩存了。那么我們就需要使用深度緩存,而所謂的深度緩存就是利用字典套字典來進(jìn)行保存的,比如下面這個(gè)函數(shù),需要傳遞兩個(gè)參數(shù),那么對(duì)應(yīng)的緩存就是:

然后就是Main中進(jìn)行調(diào)用:

      最后我們可以看到下面的這個(gè)結(jié)果,第一次調(diào)用sfunc(10,5)時(shí)建立了緩存,再第二次傳遞同樣的參數(shù)調(diào)用后可以看到控制臺(tái)并沒有輸出對(duì)應(yīng)的字符串:

      當(dāng)然這樣字典的嵌套在參數(shù)很多的情況下,會(huì)顯得很復(fù)雜,并且也會(huì)消耗很多內(nèi)存。但是當(dāng)前也沒有非常好的解決方案,下面我們還可以利用之前寫的Cache函數(shù)來實(shí)現(xiàn)上面這種多個(gè)參數(shù)的緩存:

      重點(diǎn)是我們紅色框住的那部分,具體的嵌套就是第一個(gè)字典的key是第一個(gè)參數(shù),value就是下個(gè)函數(shù)的引用,當(dāng)然這個(gè)函數(shù)是經(jīng)過Cache包裝之后的,那么自然在調(diào)用value的函數(shù)之后自然也起到了緩存作用。

相關(guān)文章

  • C#取得隨機(jī)顏色的方法

    C#取得隨機(jī)顏色的方法

    這篇文章主要介紹了C#取得隨機(jī)顏色的方法,通過自定義函數(shù)實(shí)現(xiàn)隨機(jī)顏色的功能,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-01-01
  • C#對(duì)稱加密(AES加密)每次生成的結(jié)果都不同的實(shí)現(xiàn)思路和代碼實(shí)例

    C#對(duì)稱加密(AES加密)每次生成的結(jié)果都不同的實(shí)現(xiàn)思路和代碼實(shí)例

    這篇文章主要介紹了C#對(duì)稱加密(AES加密)每次生成的結(jié)果都不同的實(shí)現(xiàn)思路和代碼實(shí)例,每次解密時(shí)從密文中截取前16位,這就是實(shí)現(xiàn)隨機(jī)的奧秘,本文同時(shí)給出了實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-07-07
  • C#實(shí)現(xiàn)HTTP上傳文件的方法

    C#實(shí)現(xiàn)HTTP上傳文件的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)HTTP上傳文件的方法,包括了發(fā)送文件與接收文件的實(shí)現(xiàn)代碼,具有不錯(cuò)的參考價(jià)值,需要的朋友可以參考下
    2014-11-11
  • C#中DataTable排序、檢索、合并等操作實(shí)例

    C#中DataTable排序、檢索、合并等操作實(shí)例

    這篇文章主要介紹了C#中DataTable排序、檢索、合并等操作實(shí)例,其中詳細(xì)介紹了DataTable.Select的一些注意問題和使用技巧等,需要的朋友可以參考下
    2014-04-04
  • 如何在c#中使用Zlib壓縮與解壓

    如何在c#中使用Zlib壓縮與解壓

    這篇文章主要介紹了如何在c#中使用Zlib壓縮與解壓,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-04-04
  • C# partial關(guān)鍵字說明

    C# partial關(guān)鍵字說明

    C# 中可以將類、結(jié)構(gòu)或接口的定義拆分到兩個(gè)或多個(gè)源文件中,在類聲明前添加partial關(guān)鍵字即可,通過本文給大家介紹C# partial關(guān)鍵字說明,需要的朋友參考下
    2016-02-02
  • C#實(shí)現(xiàn)將Doc文檔轉(zhuǎn)換成rtf格式的方法示例

    C#實(shí)現(xiàn)將Doc文檔轉(zhuǎn)換成rtf格式的方法示例

    這篇文章主要介紹了C#實(shí)現(xiàn)將Doc文檔轉(zhuǎn)換成rtf格式的方法,結(jié)合實(shí)例形式分析了C#針對(duì)word文件的讀取及文檔格式轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07
  • C#讀取計(jì)算機(jī)CPU及HDD信息的方法

    C#讀取計(jì)算機(jī)CPU及HDD信息的方法

    這篇文章主要介紹了C#讀取計(jì)算機(jī)CPU及HDD信息的方法,涉及C#讀取計(jì)算機(jī)CPU及硬盤信息的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • C#實(shí)現(xiàn)Word和ODT文檔相互轉(zhuǎn)換詳解

    C#實(shí)現(xiàn)Word和ODT文檔相互轉(zhuǎn)換詳解

    ODT文檔格式一種開放文檔格式(OpenDocument Text)。本文以C#及VB.NET代碼展示ODT和Word文檔之間相互轉(zhuǎn)換的方法,感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • C# WinForm快捷鍵設(shè)置技巧

    C# WinForm快捷鍵設(shè)置技巧

    這篇文章主要給大家介紹C# winform快捷鍵設(shè)置技巧,涉及到C winform快捷鍵相關(guān)知識(shí),對(duì)C winform知識(shí)感興趣的朋友可以參考下本篇文章
    2015-10-10

最新評(píng)論

麦盖提县| 罗甸县| 阳原县| 重庆市| 塔城市| 温泉县| 称多县| 石门县| 建德市| 屏南县| 鲁山县| 九寨沟县| 绥德县| 无极县| 阳高县| 准格尔旗| 新邵县| 芜湖市| 凤庆县| 云林县| 灵璧县| 彭阳县| 无极县| 噶尔县| 双城市| 河源市| 肥东县| 百色市| 龙口市| 南溪县| 尉犁县| 抚松县| 睢宁县| 昌乐县| 黑水县| 花莲县| 泽州县| 健康| 长宁县| 盐池县| 凯里市|