[翻譯]Goroutine效能測試

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

原文在此:http://en.munknex.net/2011/12/golang-goroutines-performance.html

————————–翻譯分割線————————–

概述

在這篇文章裡,我將嘗試評估 goroutine 的效能。goroutine 是類似輕量級線程的東西。為了提供原生的多任務,它(協同 channel 一起)被內建於Go中。

文檔告訴我們:

它實際上是在同一個地址空間裡建立成百上千個 goroutine。

因此,這個文章的重點就是測試並明確在如此巨大的並發運行函數的情況下所能承受的效能壓力上限。

記憶體

建立一個新的goroutine所需空間並未記錄在文檔中。只是說需要幾KB。在不同的機制下測試,協助確認這個數值為4—4.5kB。因此,5GB差不多足夠運行一百萬個goroutine。

效能

讓我們算算在一個 goroutine 裡運行函數會損失多少的效能吧。可能你已經知道這非常簡單——只要在函數調用前添加 go 關鍵字:

go testFunc()

goroutine 複用於線程。預設情況下,如果沒有設定 GOMAXPROCS 環境變數,程式只使用一個線程。為了利用全部 CPU 核心,則必須制定它的值。例如:

export GOMAXPROCS=2

這個值在運行時使用。因此沒有必要在每次修改這個值之後,重新編譯器。

以我的推斷,大多數時間花費在建立 goroutine,切換它們,以及從一個線程遷移 goroutine 到另外的線程,還有在不同的線程之間的 goroutine 進行通訊。為了避免無盡的論述,讓我們從僅用一個線程的情況開始。

所有測試都是在我的 nettop(譯註:英特爾公司的低成本簡易台式機解決方案)上完成的:

  • Atom D525 Dual Core 1.8 GHz
  • 4Gb DDR3
  • Go r60.3
  • Arch Linux x86_64

方法

這是測試函數產生器:

func genTest (n int) func (res chan <- interface {}) {        return func(res chan <- interface {}) {                for i := 0; i < n; i++ {                        math.Sqrt(13)                }                res <- true        }}

然後這裡是一系列分別計算 sqrt(13) 1、10、100、1000 和 5000 次的函數集合:

testFuncs := [] func (chan <- interface {}) { genTest(1), genTest(10), genTest(100), genTest(1000), genTest(5000) }

我將每個函數在迴圈中執行 X 遍,然後在 goroutine 中執行 X 遍。然後比較結果。當然,應當留意記憶體回收。為了降低其帶來的影響,我在 goroutine 結束後顯式調用了 runtime.GC() 並記錄結束時間。當然,為了測試精確性,每個測試執行了許多遍。整個已耗用時間用了大約 16 小時。

一個線程

export GOMAXPROCS=1

圖表顯示在 goroutine 中啟動並執行 sqrt() 計算工作大約比在函數中運行慢四倍。

來看看剩餘的四個函數的情況:

你會注意到,即使並發執行70萬 goroutine 也不會使得效能下降到 80% 以下。現在是最值得敬佩的地方。從 sqrt()x1000 開始,總體消耗低於 2%。5000 次——只有 1%。看起來這個數值與 goroutine 的數量無關!因此唯一的制約因素是記憶體。

概要:

如果互不依賴的代碼的執行時間高於計算平方跟的10倍,並且你希望它並發執行,應毫不猶豫的讓其在 goroutine 中運行。雖然,可以輕鬆的將10或者100個這樣的代碼放在一起,不過損失的效能僅僅分別是 20% 和 2%。

多線程

現在來看看當我們希望使用若干個處理器核心時的情況。在我的用例中是 2 個:

export GOMAXPROCS=2

再次執行我們的測試程式:

這裡你會發現,儘管核心數增加了一倍,但是前兩個函數的已耗用時間卻增加了!這極可能是線上程之間移動比執行它們的開銷要大得多。:)當前的調度器還不能處理,不過 Go 的開發人員承諾在未來會解決這種情況。

你已經看到了,最後的兩個函數完全使用了兩個核。在我的 nettop 上,他們的執行時間分別是 ~45µs 和 ~230µs。

總結

儘管這是一個年輕的語言,並且有著一個臨時的調度器實現,goroutine 的效能讓人覺得興奮。尤其是與 Go 的簡單易用結合起來的時候。這令我印象深刻。感謝 Go Team Dev!

當已耗用時間少於 1µs 我會在執行 goroutine 之前深思熟慮一下,而如果已耗用時間超過 1ms,那就決不猶豫的使用 goroutine 了。:)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.