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

C#中尾遞歸的使用、優(yōu)化及編譯器優(yōu)化

 更新時(shí)間:2015年04月10日 08:57:10   投稿:junjie  
這篇文章主要介紹了C#中尾遞歸的使用、優(yōu)化及編譯器優(yōu)化,本文講解了遞歸運(yùn)用、尾遞歸優(yōu)化、編譯器優(yōu)化等內(nèi)容,需要的朋友可以參考下

遞歸運(yùn)用

一個(gè)函數(shù)直接或間接的調(diào)用自身,這個(gè)函數(shù)即可叫做遞歸函數(shù)。

遞歸主要功能是把問(wèn)題轉(zhuǎn)換成較小規(guī)模的子問(wèn)題,以子問(wèn)題的解去逐漸逼近最終結(jié)果。
遞歸最重要的是邊界條件,這個(gè)邊界是整個(gè)遞歸的終止條件。

復(fù)制代碼 代碼如下:

static int RecFact(int x)
{
    if (x == 0)
        return 1;
    return x * RecFact(x - 1);
}
RecFact(10);

上面是個(gè)經(jīng)典階乘函數(shù)的實(shí)現(xiàn)。這里分2步:

1.轉(zhuǎn)換,把10的階乘轉(zhuǎn)化成10*9!,10(9*8!)....每次轉(zhuǎn)換規(guī)模就變的更小。
2.逼近,轉(zhuǎn)換到最小規(guī)模時(shí)0!,求解1。開(kāi)始逆向合并逐漸逼近到10,得出解。
這里的x==0就是我們的邊界條件(即終止條件),也有的依賴外部變量為邊界。

如果一個(gè)遞歸函數(shù)沒(méi)有邊界,也就無(wú)法停止(無(wú)限循環(huán)至內(nèi)存溢出),當(dāng)然這樣也沒(méi)什么意義。

RecFact調(diào)用堆棧:

常見(jiàn)使用場(chǎng)景:

1.階乘/斐波那契數(shù)列/漢諾塔
2.遍歷硬盤文件
3.InnerExceptions異常撲捉(exception.InnerException==null)

尾遞歸優(yōu)化

當(dāng)邊界不明確的時(shí)候,遞歸就很容易出現(xiàn)溢出問(wèn)題。

在階乘過(guò)程中,堆棧需要保存每次(RecFact)調(diào)用的返回地址及當(dāng)時(shí)所有的局部變量狀態(tài),期間堆??臻g是無(wú)法釋放的(即容易出現(xiàn)溢出)。

為了優(yōu)化堆棧占用問(wèn)題,從而提出尾遞歸優(yōu)化的辦法。

復(fù)制代碼 代碼如下:

static void TailRecursion(int x)
    {
        Console.WriteLine(x);
        if (x == 10)
            return;
        TailRecursion(x + 1);
    }
    TailRecursion(0);

使用尾遞歸堆??梢圆挥帽4嫔洗蔚暮瘮?shù)返回地址/各種狀態(tài)值,而方法遺留在堆棧上的數(shù)據(jù)完全可以釋放掉,這是尾遞歸優(yōu)化的核心思想。

由于尾遞歸期間,堆棧是可以釋放/再利用的,也就解決遞歸過(guò)深而引起的溢出問(wèn)題,這也是尾遞歸的優(yōu)勢(shì)所在。

編譯器優(yōu)化

尾遞歸優(yōu)化,看起來(lái)是蠻美好的,但在net中卻有點(diǎn)亂糟糟的感覺(jué)。

1.Net在C#語(yǔ)言中是JIT編譯成匯編時(shí)進(jìn)行優(yōu)化的。
2.Net在IL上,有個(gè)特殊指令tail去實(shí)現(xiàn)尾遞歸優(yōu)化的(F#中)。

我們執(zhí)行 TailRecursion(0)(x==1000000) 得出如下結(jié)論:

C#/64位/Release是有JIT編譯器進(jìn)行尾遞歸優(yōu)化的(非C#編譯器優(yōu)化)。

C#/32位或C#/Debug模式中JIT是不進(jìn)行優(yōu)化的。

F#在優(yōu)化尾遞歸也分2種情況:

1、 簡(jiǎn)單的尾遞歸優(yōu)化成while循環(huán),如下:

復(fù)制代碼 代碼如下:

let rec TailRecursion(x) =
  if (x = 1000) then true
  else TailRecursion(x + 1)

(方便演示C#呈現(xiàn))編譯器優(yōu)化成:
復(fù)制代碼 代碼如下:

public static bool TailRecursion(int x)
    {
        while (x != 0x3e8)
        {
            x++;
        }
        return true;
    }

2、 復(fù)雜的尾遞歸,F(xiàn)#編譯器會(huì)生成IL指令Tail進(jìn)行優(yōu)化,如下:
復(fù)制代碼 代碼如下:

let TailRecursion2 a cont = cont (a + 1) 

優(yōu)化成:

如何定義復(fù)雜的尾遞歸呢?通常是后繼傳遞模式(CPS)。

F#中在debug模式下,需要在編譯時(shí)配置:

總結(jié)

在C#語(yǔ)言(過(guò)程式/面向?qū)ο缶幊趟枷?中,優(yōu)先考慮的是循環(huán),而不是遞歸/尾遞歸。 但在函數(shù)式編程思想當(dāng)中,遞歸/尾遞歸使用則是主流用法,就像在C#使用循環(huán)一樣。

相關(guān)文章

  • Unity?UGUI的PhysicsRaycaster物理射線檢測(cè)組件介紹使用

    Unity?UGUI的PhysicsRaycaster物理射線檢測(cè)組件介紹使用

    這篇文章主要介紹了Unity?UGUI的PhysicsRaycaster物理射線檢測(cè)組件的介紹及使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • C# winfrom實(shí)現(xiàn)讀取修改xml

    C# winfrom實(shí)現(xiàn)讀取修改xml

    這篇文章主要為大家詳細(xì)介紹了C# winfrom實(shí)現(xiàn)讀取修改xml的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • 詳解如何在C#中使用COM接口

    詳解如何在C#中使用COM接口

    COM是一種二進(jìn)制接口標(biāo)準(zhǔn),允許軟件組件在同一進(jìn)程中、跨進(jìn)程甚至跨網(wǎng)絡(luò)透明地交互,COM接口定義了一組方法和屬性,這些方法和屬性可以通過(guò)任何支持該模型的語(yǔ)言調(diào)用來(lái)訪問(wèn),本文給大家介紹了如何在C#中使用COM接口,需要的朋友可以參考下
    2025-03-03
  • c# yield提高代碼性能和可讀性

    c# yield提高代碼性能和可讀性

    Yield可以讓你的代碼更加高效并擁有更高的可讀性,我想已經(jīng)沒(méi)有什么借口可以阻止我們學(xué)習(xí)和使用yield
    2013-12-12
  • 解決winform界面刷新閃爍問(wèn)題的多種方案

    解決winform界面刷新閃爍問(wèn)題的多種方案

    這篇文章給大家介紹了如何解決winform界面刷新閃爍問(wèn)題的多種方案,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • C#日期轉(zhuǎn)換函數(shù)分享

    C#日期轉(zhuǎn)換函數(shù)分享

    這篇文章介紹了C#日期轉(zhuǎn)換函數(shù),有需要的朋友可以參考一下
    2013-10-10
  • UnityShader3實(shí)現(xiàn)2D描邊效果

    UnityShader3實(shí)現(xiàn)2D描邊效果

    這篇文章主要為大家詳細(xì)介紹了UnityShader3實(shí)現(xiàn)2D描邊效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • C#基于Modbus三種CRC16校驗(yàn)方法的性能對(duì)比

    C#基于Modbus三種CRC16校驗(yàn)方法的性能對(duì)比

    這篇文章主要介紹了C#基于Modbus三種CRC16校驗(yàn)方法的性能對(duì)比,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • C#使用MSTest進(jìn)行單元測(cè)試

    C#使用MSTest進(jìn)行單元測(cè)試

    這篇文章介紹了C#使用MSTest進(jìn)行單元測(cè)試的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • 詳解從零開(kāi)始---用C#制作掃雷游戲

    詳解從零開(kāi)始---用C#制作掃雷游戲

    這篇文章主要介紹了詳解從零開(kāi)始---用C#制作掃雷游戲,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-06-06

最新評(píng)論

龙山县| 阜宁县| 洪洞县| 三江| 罗田县| 信丰县| 婺源县| 出国| 鹤岗市| 集安市| 大同县| 望城县| 北安市| 翁牛特旗| 寿光市| 凤凰县| 商水县| 晋城| 基隆市| 澄迈县| 张家口市| 东乌珠穆沁旗| 施甸县| 泰顺县| 天水市| 鹤峰县| 阿拉尔市| 崇义县| 手游| 辽中县| 白朗县| 潼南县| 墨玉县| 股票| 英吉沙县| 延长县| 台山市| 屏南县| 裕民县| 龙游县| 乐昌市|