golang快速入门-02

游戏视点

共 1123字,需浏览 3分钟

 ·

2023-08-07 18:34

goroutine的并发数量

不控制并发的 goroutine 数量会发生什么?

  1. CPU 使用率浮动上涨

  2. Memory 占用不断上涨

  3. 主进程崩溃(被杀掉了)原因是打开文件数量太多内存占用等对系统资源占用过大

解决方案

  1. 控制/限制 goroutine 同时并发运行的数量

  2. 改变应用程序的逻辑写法(避免大规模的使用系统资源和等待)

使用chan和sync

实现了控制 goroutine 以 2 个 2 个的数量去执行我们的 “业务逻辑”

var wg = sync.WaitGroup{}

func main() {
userCount := 10
ch := make(chan bool, 2)
for i := 0; i < userCount; i++ {
wg.Add(1)
go Read(ch, i)
}

wg.Wait()
}

func Read(ch chan bool, i int) {
defer wg.Done()

ch <- true
fmt.Printf("go func: %d, time: %d\n", i, time.Now().Unix())
time.Sleep(time.Second)
<-ch
}

循环交互赋值是性能分析

常常会遇到循环交换赋值的数据处理场景,尤其是 RPC,数据交互格式要转为 Protobuf,赋值是无法避免的。

一般会有如下几种做法:

  1. for

  2. for range

  3. json.Marshal/Unmarshal

三种做法的性能顺序为1 > 2 > 3

for range 在性能上相较 for 差 json。Marsha1最差
for range 始终使用值拷贝的方式来生成循环变量。通俗来讲,就是在每次循环时,都会对循环变量重新分配.
encoding/json 标准库,是通过大量反射来实现的, 因此很慢

总结

  1. 对性能开销有较高要求:选用 for,开销最小

  2. 中规中矩:选用 for range,大对象慎用

  3. 量小、占用小、数量可控:选用 json.Marshal/Unmarshal 的方案也可以。其重复代码少,但开销最大

为什么 Go map 遍历输出是不固定顺序?

for range map 在开始处理循环逻辑的时候,就做了随机播种.根据随机数,选择一个桶位置作为起始点进行遍历迭代.

浏览 21
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报