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

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

废话少说,贴代码:

单协程测试运算:

package main

import (
	"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 main

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

var synWait sync.WaitGroup

func 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 main

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

var synWait sync.WaitGroup
var normalMap map[int]int
var synMutex sync.Mutex

func 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 main

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

var synWait sync.WaitGroup
var normalMap map[int]int

func 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并发操作效率不及单协程(有点违背多核的感觉)。通道又比纯加锁要慢。

原文地址:https://www.cnblogs.com/huangliang-hb/p/10173175.html

时间: 2024-10-08 15:33:51

golang 单协程和多协程的性能测试的相关文章

Python的异步编程[0] -&gt; 协程[1] -&gt; 使用协程建立自己的异步非阻塞模型

使用协程建立自己的异步非阻塞模型 接下来例子中,将使用纯粹的Python编码搭建一个异步模型,相当于自己构建的一个asyncio模块,这也许能对asyncio模块底层实现的理解有更大的帮助.主要参考为文末的链接,以及自己的补充理解. 完整代码 1 #!/usr/bin/python 2 # ============================================================= 3 # File Name: async_base.py 4 # Author: L

OTA“多角恋”:携程闪电入股同程、途牛

OTA"多角恋":携程闪电入股同程.途牛 2014年04月30日 16:38 来源:南方都市报 参与互动(0) "携程将把景点门票的现付业务接入同程,并向同程投资超过2亿美金,支持同程独立IPO."4月28日晚间,同程网CEO吴志祥以发布内部邮件的形式,"向大家报告一个好消息." 而就在十来天前,同程旅游刚与艺龙旅行网签署了战略合作协议.据业内知情人士透露,伴随此次入股,携程与同程之间签署了一份"缓冲期"协议.即一年后,同程将

Unity在协程内部停止协程自身后代码执行问题

当在协程内部停止自身后,后面的代码块还会继续执行,直到遇到yield语句才会终止. 经测试:停止协程,意味着就是停止yield,所以在停止协程后,yield之后的语句也就不会执行了. 代码如下: 1 using UnityEngine; 2 using System.Collections; 3 4 public class Test : MonoBehaviour { 5 6 void Start () { 7 StartCoroutine("Method"); 8 } 9 10 I

golang 创建超过10万个Go程时报错stackcacherefill

package main import(     //"fmt"     "time" ) var c = make(chan int,100) func gofunc(){     time.Sleep(0)     c<-0 } func main(){     for i:=0;i<10;i++{         for j:=0;j<10000;j++{             go gofunc()             }      

携程旅行app|携程旅行app下载

中国旅游市场近年保持持续发展的态势,国民旅游消费需求旺盛.来自中国社科院的研究显示,2015年我国国内旅游和出境旅游人次分别达40亿和1.2亿,国内旅游收入达3.6万亿.其中,旅游产业线上***率为11.5%,2015年中国在线旅游市场交易规模已达4737.7亿元.在中国在线旅游市场持续成长的背景下,预计未来OTA在整体旅游产业所占交易规模比重将进一步扩大.携程旅行app下载链接软件介绍携程旅行一款在线旅行服务软件.该软件的口号是携程在手说走就走.该软件可以提供提供酒店.机票.火车票.汽车票.景

山一程,水一程,身向榆关那畔行,夜深千帐灯。

近日路过三元湖畔,惊奇的发现荷花长势大好,悄然之间竟占据了大半个湖伴着舒适的阳光真真的叫人享受呢.又不禁感慨荷花长的可是真快,从而联想到一年多前.高考也过了一年了,时间它真是神奇的元素,有时你觉得过的很慢,有时候你觉得过得很快.不经意间它就悄然流逝,抓都抓不到. 一年高考前的那段时间可谓折磨人啊,那之前很长一段时间患得患失,竟愚蠢到把复读天天挂在嘴边.成绩的起起伏伏总是胡思乱想,可谓让人不愿再想起,那年高考天气就如往常一般烤人,骑着单车不久身上的短袖就被汗水浸湿.显然一直患得患失的人是无法在高考

操作系統-進程管理4(線程)

操作系统-进程管理(线程) 线程 线程的基本概念 线程是比进程更小的.能够独立运行的基本单位,线程比进程能更好地提高程序的并行执行速度,充分利用多处理机的优越性.引用线程主要是为了提高系统的处理效率,减少处理机的空转时间和进行调度时因保护CPU现场浪费的时间. 线程是进程中执行运算的最小单位,即执行处理机调度的基本单位.在引入线程的操作系统中,可以在一个进程内部进行线程的切换. 进程是资源分配的基本单位,同一进程的所有线程共享该进程的所有资源.线程是分配处理机的基本单位,真正在处理机上运行的是线

操作系統-進程管理2(進程的互斥與同步)

操作系统-进程管理2(进程的同步与互斥) 进程的同步与互斥 两个或两个以上的进程不能同时使用的资源称为临界资源.临界资源的存在带来了进程之间的互斥访问的问题. 进程互斥:逻辑上完全独立.毫无关系的两个进程因为竞争同一块资源而相互制约,称为进程互斥. 进程同步:有协作关系的进程不断调整它们之间的相对速度或执行过程,以保证临界资源的合理利用和进程的顺利执行.一般借由中间媒体实现:如信号量操作.加锁操作等.同步机制应遵循的规则: 空闲让进 忙则等待 有限等待:进程等待进入临界区的时间必须是有限的,避免

利用jmeter+JAVA对RPC的单接口(dubbo接口等)进行性能测试

建立JAVA项目 建立maven项目,加入Jmeter所需要的JAR包依赖. POM.xml  加入如下: <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_core</artifactId> <version>3.2</version> </dependency> <!-- https://mvnrepo