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

废话少说,贴代码:

单协程测试运算:

运行时间为:0.065330877

多协程测试运算:

运行时间为:0.019804929

 

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

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

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

 

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

单协程/多协程测试map:

 

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

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

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

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

原因为什么呢???这篇博客有所阐述:https://www.cnblogs.com/ipub520/p/7718905.html

 

协程通道测试map:

运行时间为:53.554329275  

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

不要通过共享内存来通信,而要通过通信来共享内存!

slice也是和map差不多的,并发append的时候也必须加锁

我们举一个简单例子,比如,当A和B两个协程运行append的时候同时发现s[1]这个位置是空的,他们就都会把自己的值放在这个位置,这样他们两个的值就会覆盖,造成数据丢失。

 

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

多协程去运算确实快比单协程要快,因为golang会默认根据多核去跑,但是如果操作涉及到加锁的时候(例如map,slice),就要注意,并发操作效率不及单协程(这点和erlang操作ets不一样,erlang恰好相反)。