1. 程式人生 > >Go 提高效能的特性

Go 提高效能的特性

1、值的高效處理和儲存,允許建立緊湊的資料結構,避免不必要的填充位元組。緊湊的資料結構能更好地利用快取。更好的快取利用率可帶來更好的效能。

2、函式的呼叫有開銷,減少函式呼叫開銷的解決方案是內聯。簡單的函式可以被 Go 編譯器內聯。

3、強制垃圾回收使 Go 成為一種更簡單,更安全的語言。這意味著在堆上分配的記憶體是有代價的。每次 GC 執行時都會花費 CPU 時間,直到釋放記憶體為止。逃逸分析的重要性,增加變數在棧分配,減少在堆分配。

4、程序切換的開銷很大,所以出現了執行緒,共享相同的記憶體空間。由於執行緒共享地址空間,因此它們比程序更輕,因此建立速度更快,切換速度更快。Goroutine 昇華了執行緒。

  Goroutine 可能會給禪讓給其他協程時刻是:

  • 阻塞式通道傳送和接收。

  • Go 宣告,雖然不能保證會立即排程新的 goroutine。

  • 檔案和網路操作式的阻塞式系統呼叫。

  • 在被垃圾回收迴圈停止後。

  每一個 Go 程序的作業系統執行緒相對較少,Go 執行時負責將可執行的 Goroutine 分配給空閒的作業系統執行緒。

5、程序地址空間有堆、棧來儲存變數,堆自下而上,棧自上而下,防止相互穿透,有保護頁,稱為不可寫記憶體區域。每個執行緒都會分配自己的棧,隨著程式中執行緒數的增加,可用地址空間的數量會減少。Go 編譯器不使用保護頁,而是在每個函式呼叫時插入一個檢查,以檢查是否有足夠的棧來執行該函式。如果沒有,執行時可以分配更多的棧空間。為了解決熱分裂問題,Go 1.3 採用了一種新的棧管理方法。如果 goroutine 的棧太小,則不會新增和刪除其他棧段,而是分配新的更大的棧。舊棧的內容被複制到新棧,然後 goroutine 使用新的更大的棧繼續執行。

 

總結:這五個特性一樣強大,它們不是孤立存在的。例如,執行時將 goroutine 複用到執行緒上的方式在沒有可擴充套件棧的情況下幾乎沒有效率。內聯通過將較小的函式組合成較大的函式來降低棧大小檢查的成本。逃逸分析通過自動將從例項從堆移動到棧來減少垃圾回收器的壓力。逃逸分析還提供了更好的快取區域性性Cache Locality。如果沒有可增長的棧,逃逸分析可能會對棧施加太大的壓力。