golang 单协程和多协程的性能测试

golang 单协程和多协程的性能测试,第1张

概述测试数据:单协程 *** 作1亿数据,以及多协程(10条协程) *** 作1亿数据(每条协程 *** 作1kw数据) 废话少说,贴代码: 单协程测试运算: package mainimport ( "fmt" "time")func testNum(num int) { for i := 1; i <= 10000000; i++{ num = num + i num = num - i nu

测试数据:单协程 *** 作1亿数据,以及多协程(10条协程) *** 作1亿数据(每条协程 *** 作1kw数据)

废话少说,贴代码:

单协程测试运算:

package mainimport (	"fmt"	"time")func testNum(num int) {	for i := 1; i <= 10000000; i++{		num = num + i		num = num - i		num = num * i		num = num / i	}}func main() {	start := time.Now()	for i := 1; i <= 10; i++ {		testNum(1)	}	end :=  time.Now()	fmt.Println(end.Sub(start).Seconds())}

运行时间为:0.065330877

多协程测试运算:

package mainimport (	"fmt"	"time"	"sync")var synWait sync.WaitGroupfunc testNum(num int) {	for i := 1; i <= 10000000; i++{		num = num + i		num = num - i		num = num * i		num = num / i	}	synWait.Done() 	// 相当于 synWait.Add(-1)}func main() {	start := time.Now()	for i := 1; i <= 10; i++ {		synWait.Add(1)		go testNum(1)	}	synWait.Wait()	end :=  time.Now()	fmt.Println(end.Sub(start).Seconds())} 

运行时间为:0.019804929

 

比较结果,和预期的是一样,多协程要比单协程处理数据快,很多人还会去设置runtime.GOMAXPROCS(x),其实

这是远古程序员的做法了,因为go 1.6以上的版本就已经会自动根据计算机核的调用啦!!!

如果没有调用runtime.GOMAXPROCS 去设置cpu,Golang默认使用所有的cpu核

 

以下是以map来做实验,为了测试准确性,统一都加锁

单协程/多协程测试map:

package mainimport (	"fmt"	"time"	"sync")var synWait sync.WaitGroupvar normalMap map[int]intvar synMutex sync.Mutexfunc testNum(num int) {	for i := 1; i <= 10000000; i++{		synMutex.Lock()		normalMap[i] = num		synMutex.Unlock()	}	synWait.Done() 	// 相当于 synWait.Add(-1)}func main() {	normalMap = make(map[int]int)	start := time.Now()	for i := 1; i <= 10; i++ {		synWait.Add(1)		testNum(1)		// 单协程 *** 作		//go testNum(1)		// 多协程并发 *** 作	}	synWait.Wait()	end :=  time.Now()	fmt.Println(end.Sub(start).Seconds())}

 

单协程 *** 作 testNum(1), 运行时间为:19.101255922

多协程 *** 作 go testNum(1), 运行时间为:28.210580532

是不是出乎意料!!! 多协程 *** 作map反而慢,这说明map这个数据结构对并发 *** 作效率比较低,如果在保证线性安全的前提下

尽量单协程去 *** 作map,如果上面代码注释掉加锁,单协程 *** 作就更快了, 运行时间为:16.307839364

 

协程通道测试map:

package mainimport (	"fmt"	"time"	"sync")var synWait sync.WaitGroupvar normalMap map[int]intfunc testNum(data chan int,num int) {	for i:=1;i<=10000000;i++{		data <- i	}	synWait.Done()}func main() {	normalMap = make(map[int]int)	data := make(chan int)	start := time.Now()	go concurrent(data)	for i := 1; i <= 10; i++ {		synWait.Add(1)		go testNum(data,1)		// 多协程并发 *** 作	}	synWait.Wait()	end :=  time.Now()	fmt.Println(end.Sub(start).Seconds())}func concurrent(data chan int)  {	for {		i := <- data		normalMap[i] = i	}}

运行时间为:53.554329275  

通道内部实现也是加锁,这肯定是要比纯用锁慢一点的,这也正好验证了(网上有些人说通道要比加锁快,这是错误的)。但是使用通道是golang的一种哲学意义,规定了入口,里面的数据

结构就不要再担忧,是否要加锁了,因为全部都是安全的(可以避免很多BUG,毕竟程序大部分问题还是出自程序员的逻辑代码),还是那句话不要通过共享内存来通信,而要通过通信来共享内存!

 

总结一下吧:(map性能 单协程 > 多协程 > 通道 )

多协程去运算确实快比单协程要快,因为golang会默认根据多核去跑,但是 *** 作map的时候,就要注意,map并发 *** 作效率不及单协程(有点违背多核的感觉)。通道又比纯加锁要慢。

总结

以上是内存溢出为你收集整理的golang 单协程和多协程的性能测试全部内容,希望文章能够帮你解决golang 单协程和多协程的性能测试所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1269062.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-08
下一篇2022-06-08

发表评论

登录后才能评论

评论列表(0条)

    保存