真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語言遞歸優(yōu)化,go語言進階

為什么要使用 Go 語言?Go 語言的優(yōu)勢在哪里

1、學習曲線

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、重慶小程序開發(fā)、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了岱山免費建站歡迎大家使用!

它包含了類C語法、GC內(nèi)置和工程工具。這一點非常重要,因為Go語言容易學習,所以一個普通的大學生花一個星期就能寫出來可以上手的、高性能的應用。在國內(nèi)大家都追求快,這也是為什么國內(nèi)Go流行的原因之一。

2、效率

Go擁有接近C的運行效率和接近PHP的開發(fā)效率,這就很有利的支撐了上面大家追求快速的需求。

3、出身名門、血統(tǒng)純正

之所以說Go語言出身名門,是因為我們知道Go語言出自Google公司,這個公司在業(yè)界的知名度和實力自然不用多說。Google公司聚集了一批牛人,在各種編程語言稱雄爭霸的局面下推出新的編程語言,自然有它的戰(zhàn)略考慮。而且從Go語言的發(fā)展態(tài)勢來看,Google對它這個新的寵兒還是很看重的,Go自然有一個良好的發(fā)展前途。我們看看Go語言的主要創(chuàng)造者,血統(tǒng)純正這點就可見端倪了。

4、組合的思想、無侵入式的接口

Go語言可以說是開發(fā)效率和運行效率二者的完美融合,天生的并發(fā)編程支持。Go語言支持當前所有的編程范式,包括過程式編程、面向?qū)ο缶幊桃约昂瘮?shù)式編程。

5、強大的標準庫

這包括互聯(lián)網(wǎng)應用、系統(tǒng)編程和網(wǎng)絡(luò)編程。Go里面的標準庫基本上已經(jīng)是非常穩(wěn)定,特別是我這里提到的三個,網(wǎng)絡(luò)層、系統(tǒng)層的庫非常實用。

6、部署方便

我相信這一點是很多人選擇Go的最大理由,因為部署太方便,所以現(xiàn)在也有很多人用Go開發(fā)運維程序。

7、簡單的并發(fā)

它包含降低心智的并發(fā)和簡易的數(shù)據(jù)同步,我覺得這是Go最大的特色。之所以寫正確的并發(fā)、容錯和可擴展的程序如此之難,是因為我們用了錯誤的工具和錯誤的抽象,Go可以說這一塊做的相當簡單。

8、穩(wěn)定性

Go擁有強大的編譯檢查、嚴格的編碼規(guī)范和完整的軟件生命周期工具,具有很強的穩(wěn)定性,穩(wěn)定壓倒一切。那么為什么Go相比于其他程序會更穩(wěn)定呢?這是因為Go提供了軟件生命周期的各個環(huán)節(jié)的工具,如go

tool、gofmt、go test。

go語言 使用遞歸與循環(huán)兩種方式計算斐波那契數(shù)列

給定一個正整數(shù)n計算出對應斐波那契數(shù)列對應的值

說明:

用mackbookpro i7 2.7GHZ筆記本進行測試,結(jié)果如下:

備注: 當n=80時,由于測試等待時間過長,強制中斷了執(zhí)行。

從測試結(jié)果看出,當n逐漸增大,遞歸方式計算斐波拉契數(shù)列的時間復雜性急劇增加。當n值較大時可以考慮用循環(huán)方式代替。

類似的方式也可以用于,求階乘、遍歷目錄、漢諾塔等問題的解決。在后期的文章中,我將這些內(nèi)容進行補充,敬請期待,謝謝。

1.14版本defer性能大幅度提升,內(nèi)部實現(xiàn)了開放編碼優(yōu)化

GO中的defer會在當前函數(shù)返回前執(zhí)行傳入的函數(shù),常用于關(guān)閉文件描述符,關(guān)閉鏈接及解鎖等操作。

Go語言中使用defer時會遇到兩個常見問題:

接下來我們來詳細處理這兩個問題。

官方有段對defer的解釋:

這里我們先來一道經(jīng)典的面試題

你覺得這個會打印什么?

輸出結(jié)果:

這里是遵循先入后出的原則,同時保留當前變量的值。

把這道題簡化一下:

輸出結(jié)果

上述代碼輸出似乎不符合預期,這個現(xiàn)象出現(xiàn)的原因是什么呢?經(jīng)過分析,我們發(fā)現(xiàn)調(diào)用defer關(guān)鍵字會立即拷貝函數(shù)中引用的外部參數(shù),所以fmt.Println(i)的這個i是在調(diào)用defer的時候就已經(jīng)賦值了,所以會直接打印1。

想要解決這個問題也很簡單,只需要向defer關(guān)鍵字傳入匿名函數(shù)

這里把一些垃圾回收使用的字段忽略了。

中間代碼生成階段cmd/compile/internal/gc/ssa.go會處理程序中的defer,該函數(shù)會根據(jù)條件不同,使用三種機制來處理該關(guān)鍵字

開放編碼、堆分配和棧分配是defer關(guān)鍵字的三種方法,而Go1.14加入的開放編碼,使得關(guān)鍵字開銷可以忽略不計。

call方法會為所有函數(shù)和方法調(diào)用生成中間代碼,工作內(nèi)容:

defer關(guān)鍵字在運行時會調(diào)用deferproc,這個函數(shù)實現(xiàn)在src/runtime/panic.go里,接受兩個參數(shù):參數(shù)的大小和閉包所在的地址。

編譯器不僅將defer關(guān)鍵字轉(zhuǎn)成deferproc函數(shù),還會通過以下三種方式為所有調(diào)用defer的函數(shù)末尾插入deferreturn的函數(shù)調(diào)用

1、在cmd/compile/internal/gc/walk.go的walkstmt函數(shù)中,在遇到ODEFFER節(jié)點時會執(zhí)行Curfn.Func.SetHasDefer(true),設(shè)置當前函數(shù)的hasdefer屬性

2、在ssa.go的buildssa會執(zhí)行s.hasdefer = fn.Func.HasDefer()更新hasdefer

3、在exit中會根據(jù)hasdefer在函數(shù)返回前插入deferreturn的函數(shù)調(diào)用

runtime.deferproc為defer創(chuàng)建了一個runtime._defer結(jié)構(gòu)體、設(shè)置它的函數(shù)指針fn、程序計數(shù)器pc和棧指針sp并將相關(guān)參數(shù)拷貝到相鄰的內(nèi)存空間中

最后調(diào)用的return0是唯一一個不會觸發(fā)延遲調(diào)用的函數(shù),可以避免deferreturn的遞歸調(diào)用。

newdefer的分配方式是從pool緩存池中獲?。?/p>

這三種方式取到的結(jié)構(gòu)體_defer,都會被添加到鏈表的隊頭,這也是為什么defer按照后進先出的順序執(zhí)行。

deferreturn就是從鏈表的隊頭取出并調(diào)用jmpdefer傳入需要執(zhí)行的函數(shù)和參數(shù)。

該函數(shù)只有在所有延遲函數(shù)都執(zhí)行后才會返回。

如果我們能夠?qū)⒉糠纸Y(jié)構(gòu)體分配到棧上就可以節(jié)約內(nèi)存分配帶來的額外開銷。

在call函數(shù)中有在棧上分配

在運行期間deferprocStack只需要設(shè)置一些未在編譯期間初始化的字段,就可以將棧上的_defer追加到函數(shù)的鏈表上。

除了分配的位置和堆的不同,其他的大致相同。

Go語言在1.14中通過開放編碼實現(xiàn)defer關(guān)鍵字,使用代碼內(nèi)聯(lián)優(yōu)化defer關(guān)鍵的額外開銷并引入函數(shù)數(shù)據(jù)funcdata管理panic的調(diào)用,該優(yōu)化可以將 defer 的調(diào)用開銷從 1.13 版本的 ~35ns 降低至 ~6ns 左右。

然而開放編碼作為一種優(yōu)化 defer 關(guān)鍵字的方法,它不是在所有的場景下都會開啟的,開放編碼只會在滿足以下的條件時啟用:

如果函數(shù)中defer關(guān)鍵字的數(shù)量多于8個或者defer處于循環(huán)中,那么就會禁用開放編碼優(yōu)化。

可以看到這里,判斷編譯參數(shù)不用-N,返回語句的數(shù)量和defer數(shù)量的乘積小于15,會啟用開放編碼優(yōu)化。

延遲比特deferBitsTemp和延遲記錄是使用開放編碼實現(xiàn)defer的兩個最重要的結(jié)構(gòu),一旦使用開放編碼,buildssa會在棧上初始化大小為8個比特的deferBits

延遲比特中的每一個比特位都表示該位對應的defer關(guān)鍵字是否需要被執(zhí)行。延遲比特的作用就是標記哪些defer關(guān)鍵字在函數(shù)中被執(zhí)行,這樣就能在函數(shù)返回時根據(jù)對應的deferBits確定要執(zhí)行的函數(shù)。

而deferBits的大小為8比特,所以該優(yōu)化的條件就是defer的數(shù)量小于8.

而執(zhí)行延遲調(diào)用的時候仍在deferreturn

這里做了特殊的優(yōu)化,在runOpenDeferFrame執(zhí)行開放編碼延遲函數(shù)

1、從結(jié)構(gòu)體_defer讀取deferBits,執(zhí)行函數(shù)等信息

2、在循環(huán)中依次讀取執(zhí)行函數(shù)的地址和參數(shù)信息,并通過deferBits判斷是否要執(zhí)行

3、調(diào)用reflectcallSave執(zhí)行函數(shù)

1、新加入的defer放入隊頭,執(zhí)行defer時是從隊頭取函數(shù)調(diào)用,所以是后進先出

2、通過判斷defer關(guān)鍵字、return數(shù)量來判斷是否開啟開放編碼優(yōu)化

3、調(diào)用deferproc函數(shù)創(chuàng)建新的延遲調(diào)用函數(shù)時,會立即拷貝函數(shù)的參數(shù),函數(shù)的參數(shù)不會等到真正執(zhí)行時計算


網(wǎng)站標題:go語言遞歸優(yōu)化,go語言進階
網(wǎng)站網(wǎng)址:http://weahome.cn/article/hoshsd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部