2017-08-01 35 views
-2

我已經開始學習Go了,它很有趣也很容易。但是在goroutines工作中,我看不到有什麼好處。Goroutine性能

如果我嘗試在2個功能依次加1萬個號碼兩次:

package main 

import (
    "fmt" 
    "time" 
) 

var sumA int 
var sumB int 

func fSumA() { 
    for i := 0; i < 1000000; i++ { 
     sumA += i 
    } 
} 

func fSumB() { 
    for i := 0; i < 1000000; i++ { 
     sumB += i 
    } 
} 

func main() { 
    start := time.Now() 
    fSumA() 
    fSumB() 
    sum := sumA + sumB 
    fmt.Println("Elapsed time", time.Since(start)) 
    fmt.Println("Sum", sum) 
} 

它需要5毫秒。

MacBook-Pro-de-Pedro:hello pedro$ ./bin/hello 
Elapsed time 5.724406ms 
Suma total 999999000000 
MacBook-Pro-de-Pedro:hello pedro$ ./bin/hello 
Elapsed time 5.358165ms 
Suma total 999999000000 
MacBook-Pro-de-Pedro:hello pedro$ ./bin/hello 
Elapsed time 5.042528ms 
Suma total 999999000000 
MacBook-Pro-de-Pedro:hello pedro$ ./bin/hello 
Elapsed time 5.469628ms 
Suma total 999999000000 

當我試圖做同樣的事情用2個夠程:

package main 

import (
    "fmt" 
    "sync" 
    "time" 
) 

var wg sync.WaitGroup 

var sumA int 
var sumB int 

func fSumA() { 
    for i := 0; i < 1000000; i++ { 
     sumA += i 
    } 
    wg.Done() 
} 

func fSumB() { 
    for i := 0; i < 1000000; i++ { 
     sumB += i 
    } 
    wg.Done() 
} 

func main() { 
    start := time.Now() 
    wg.Add(2) 
    go fSumA() 
    go fSumB() 
    wg.Wait() 
    sum := sumA + sumB 
    fmt.Println("Elapsed time", time.Since(start)) 
    fmt.Println("Sum", sum) 
} 

我得到或多或少相同的結果,5毫秒。我的電腦是MacBook Pro(Core 2 Duo)。我沒有看到任何性能改進。也許是處理器?

MacBook-Pro-de-Pedro:hello pedro$ ./bin/hello 
Elapsed time 5.258415ms 
Suma total 999999000000 
MacBook-Pro-de-Pedro:hello pedro$ ./bin/hello 
Elapsed time 5.528498ms 
Suma total 999999000000 
MacBook-Pro-de-Pedro:hello pedro$ ./bin/hello 
Elapsed time 5.273565ms 
Suma total 999999000000 
MacBook-Pro-de-Pedro:hello pedro$ ./bin/hello 
Elapsed time 5.539224ms 
Suma total 999999000000 
+5

我想你大大高估了你的CPU可以達到100萬的速度。即使毫秒級顯示也不足以完成這項工作。 5ms幾乎是所有進程啓動,並打印到控制檯。 – captncraig

+0

另外,你正在運行什麼版本。 '去版本'? – captncraig

+1

如果您想對此類基準進行測試,請使用'go test'基準。它至少會讓你得到一個合理的輸入數字,並平均執行很多次的結果。 – JimB

回答

2

在這裏,您可以怎樣利用golangs測試這個自帶Benchmark工具:

創建一個測試去文件(例如main_test.go)。

注意:_test.go必須以文件結尾!

將以下代碼複製有或創建自己的基準:

package main 

import (
    "sync" 
    "testing" 
) 

var GlobalInt int 

func BenchmarkCount(b *testing.B) { 
    var a, c int 
    count(&a, b.N) 
    count(&c, b.N) 
    GlobalInt = a + c // make sure the result is actually used 
} 

func count(a *int, max int) { 
    for i := 0; i < max; i++ { 
     *a += i 
    } 
} 

var wg sync.WaitGroup 

func BenchmarkCountConcurrent(b *testing.B) { 
    var a, c int 
    wg.Add(2) 
    go countCon(&a, b.N) 
    go countCon(&c, b.N) 
    wg.Wait() 

    GlobalInt = a + c // make sure the result is actually used 
} 

func countCon(a *int, max int) { 
    for i := 0; i < max; i++ { 
     *a += i 
    } 
    wg.Done() 
} 

運行帶:

go test -bench . 

在我的Mac結果:

$ go test -bench . 
BenchmarkCount-8    500000000   3.50 ns/op 
BenchmarkCountConcurrent-8  2000000000   1.98 ns/op 
PASS 
ok  MyPath/MyPackage  6.309s 

最重要的價值是時間/操作。越小越好。這裏3.5 ns/op用於正常計數,1.98 ns/op用於併發計數。

編輯: 在這裏你可以閱讀golang Testing and Benchmark

+0

@Pedro:你在我的答案中錯過了什麼。如果不是,你能把它標記爲正確嗎? – TehSphinX