并发与同步[封闭]的性能比较
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发与同步[封闭]的性能比较相关的知识,希望对你有一定的参考价值。
我试图在Go中测量并发的性能,但得到了意想不到的结果,以下是我写的两个程序,它们给出了相同的结果
第一个节目
package main
import (
"fmt"
"time"
)
func looper(n int,c chan int) {
sum := 0
for i :=1 ;i < n; i++{
sum = sum + i
}
c <- sum
}
func main() {
start := time.Now()
n := 10000000
c := make(chan int)
go looper(n, c)
go looper(n, c)
go looper(n, c)
go looper(n, c)
<- c
<- c
<- c
<- c
end := time.Now()
fmt.Printf("took %v", end.Sub(start))
}
第二程序:
package main
import (
"fmt"
"time"
)
func looper(n int) (sum int) {
for i :=1 ;i < n; i++{
sum = sum + i
}
return sum
}
func main() {
start := time.Now()
n := 10000000
looper(n)
looper(n)
looper(n)
looper(n)
end := time.Now()
fmt.Printf("took %v", end.Sub(start))
}
但第一程序的运行时间比第二程序的运行时间要长。我的预期恰恰相反,为什么第二个程序比第一个程序快?为什么第二个程序比第一个程序快?
答案
在线代码执行平台不能用于性能测试(特别是涉及到并发时),因为1)你无法知道他们的设置是什么,2)他们很可能严重限制了可用的核心数量。
你也应该使用 基准,它们会比自己计算时间更可靠。
也就是说,你的例子没有错,在真实的环境中,它们会产生预期的结果。例如,如果我改变 n
到 10000000000
并在我的机器上运行这两个测试,我得到了以下结果。
$ go build test1.go && time ./test1
took 2.631567986s
real 0m2.633s
user 0m10.014s
sys 0m0.016s
$ go build test2.go && time ./test2
took 9.585642986s
real 0m9.587s
user 0m9.586s
sys 0m0.008s
请注意,他们花费了大约相同的时间 user
的时间。这是因为第一个程序使用了4个核心。但由于它的并发性,使得它只需要2.6s的 real
时间。
现在,如果我用原来的 n := 10000000
,我获得。
$ go build test1.go && time ./test1
took 5.167403ms
real 0m0.006s
user 0m0.017s
sys 0m0.000s
$ go build test2.go && time ./test2
took 10.059712ms
real 0m0.011s
user 0m0.012s
sys 0m0.000s
结果太接近了,无法判断(特别是当只运行一次时)。这是因为所做的工作与设置四个goroutine的成本相比太便宜了。
以上是关于并发与同步[封闭]的性能比较的主要内容,如果未能解决你的问题,请参考以下文章
操作系统(二 )| 进程(概念特征状态进程控制进程同步机制信号量应用同步机制遵循规则程序执行特点线程引入目的与进程的区别)