Buffered channel、slice和mutex的简单性能测试

测试代码:
package main

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

const COUNT = 1000000

func bench1(ch chan int) time.Duration {
    t := time.Now()
    for i := 0; i < COUNT; i++ {
        ch <- i
    }
    var v int
    for i := 0; i < COUNT; i++ {
        v = <-ch
    }
    _ = v
    return time.Now().Sub(t)
}

func bench2(s []int) time.Duration {
    t := time.Now()
    for i := 0; i < COUNT; i++ {
        s[i] = i
    }
    var v int
    for i := 0; i < COUNT; i++ {
        v = s[i]
    }
    _ = v
    return time.Now().Sub(t)
}

func bench3(s []int, mutex *sync.Mutex) time.Duration {
    t := time.Now()
    for i := 0; i < COUNT; i++ {
        mutex.Lock()
        s[i] = i
        mutex.Unlock()
    }
    var v int
    for i := 0; i < COUNT; i++ {
        mutex.Lock()
        v = s[i]
        mutex.Unlock()
    }
    _ = v
    return time.Now().Sub(t)
}

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    ch := make(chan int, COUNT)
    s := make([]int, COUNT)
    var mutex sync.Mutex
    fmt.Println("channel\tslice\tmutex_slice")
    for i := 0; i < 10; i++ {
        fmt.Printf("%v\t%v\t%v\n", bench1(ch), bench2(s), bench3(s, &mutex))
    }
}

测试环境

CPU: i7-3770

MEMORY: 32G

OS: ubuntu12.04 x86_64

GO VERSION: 1.0.3

输出:

channel

slice

mutex_slice

53.774ms

1.735ms

37.103ms

52.978ms

1.058ms

36.928ms

52.864ms

1.058ms

36.928ms

53.337ms

1.069ms

38.073ms

53.695ms

1.055ms

37.801ms

53.45ms

1.063ms

37.683ms

53.678ms

1.161ms

37.767ms

3.568ms

1.052ms

37.792ms

53.47ms

1.06ms

37.185ms

52.78ms

1.062ms

36.899ms

结论:

在没有竞争的情况下,缓冲信道比线程锁稍慢,但执行时间是直接对数组读写的40~50倍。

引申:

对于之前的提到的内存分配器,或者其他类型的资源分配器,如果频繁调用的话,还是限制在goroutine内存分配器更合适。应该尽量避免在goroutine间分配资源。当然,实际的性能调整应该基于profile定位性能瓶颈而不是单纯的想象。

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2016-08-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Jackson0714

好用的SQL TVP~~独家赠送[增-删-改-查]的例子

1674
来自专栏小筱月

java ssm框架实现分页功能 (oracle)

LIMIT a,b : 参数 a:第 a 条数据开始查询(不包括第 a 条), 参数 b:查询 b 条数据

8232
来自专栏张善友的专栏

性能计数器数据收集服务

本文演示了一个Windows服务收集性能计数器的数据,将性能计数器数据写入数据库。Windows服务中调用WebAPI服务中。下面简要介绍下我的改造,项目虽小,...

2558
来自专栏王亚昌的专栏

实战设计模式系列-Singleton(单件)

    单件模式的应用场景大家都不陌生,目的也很明确,就是一个类保证只有一个实际,比如项目中的资源管理器,或打log的类,都比较适合单件模式,话不多说,先贴一段...

741
来自专栏Jerry的SAP技术分享

如何将S/4HANA系统存储的图片文件用Java程序保存到本地

然后我把这段代码封装到一个Function moduleZDIS_GET_MATERIAL_IMAGES里,在Java代码里消费这个function modul...

1131
来自专栏PPV课数据科学社区

【学习】七天搞定SAS(五):数据操作与合并

数据集操作永远是逃不掉的问题,最简单的就是两个数据集的合并——当然不是简简单单的行列添加,按照某一主键或者某些主键合并才是最常用的。在SAS中,要熟悉的就是SE...

39811
来自专栏菩提树下的杨过

silverlight的独立存储

这个东西有点象Flash的Cookie,可以用来在客户端存储一些数据,我在官方文档上读到这个功能的第一反应就是:用它来做IM的客户端聊天记录存储太棒了,呵呵 ...

2205
来自专栏前期

python 分析设备日志统计在线时间

2018-03-01 00:13:52,815 [protocol.handler.1][INFO] - cn.testin.trans.controller....

920
来自专栏杨建荣的学习笔记

关于db_files和maxdatafiles的问题(r4笔记第31天)

昨天在做生产监控的时候发现有个库的表空间不够了,就发邮件给客户的dba去处理,但是得到的反馈是尝试添加的时候发现已经超过了数据文件的最大数限制。这个错误毫无疑问...

3596
来自专栏Java帮帮-微信公众号-技术文章全总结

Hibernate_day03总结

Hibernate_day03总结 今日内容 l Hibernate的检索方式 l Hibernate的抓取策略 l Hibernate的批量检索 l 事务的并...

2443

扫码关注云+社区

领取腾讯云代金券