协程性能
Goroutine performance
我开始学围棋了,既有趣又简单。但是使用 goroutines 我没有看到性能上的好处。
如果我尝试在 2 个函数中两次连续添加 100 万个数字:
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 个 goroutine 做同样的事情时:
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
在这里你可以如何使用 golangs 自己的基准测试工具来测试它:
创建一个测试文件(例如main_test.go
)。
Note: _test.go
has to be the file ending!
在那里复制以下代码或创建您自己的基准:
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
最重要的值是 time/op。越小越好。这里3.5ns/op为正常计数,1.98ns/op为并发计数
编辑:
在这里你可以阅读 golang Testing and Benchmark.
我开始学围棋了,既有趣又简单。但是使用 goroutines 我没有看到性能上的好处。
如果我尝试在 2 个函数中两次连续添加 100 万个数字:
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 个 goroutine 做同样的事情时:
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
在这里你可以如何使用 golangs 自己的基准测试工具来测试它:
创建一个测试文件(例如main_test.go
)。
Note:
_test.go
has to be the file ending!
在那里复制以下代码或创建您自己的基准:
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
最重要的值是 time/op。越小越好。这里3.5ns/op为正常计数,1.98ns/op为并发计数
编辑: 在这里你可以阅读 golang Testing and Benchmark.