为了账号安全,请及时绑定邮箱和手机立即绑定

如何对通道/互斥内存消耗/分配进行基准测试?

如何对通道/互斥内存消耗/分配进行基准测试?

Go
猛跑小猪 2022-05-10 15:54:23
我尝试比较使用通道获取一个值与使用互斥锁。频道示例:func BenchmarkNewDummy(b *testing.B) {    one := make(chan string, 1)    two := make(chan string, 1)    var wg sync.WaitGroup    wg.Add(2)    go doWork(&wg, one)    go doWork(&wg, two)    wg.Wait()    fmt.Println(<-one)    fmt.Println(<-two)}func doWork(wg *sync.WaitGroup, one chan string) {    defer wg.Done()    one <- "hell0"}命令:go test -bench=. -benchmem -run BenchmarkNewDummy -cpuprofile cpuCh.out -memprofile memCh.prof 输出没有提供任何有用的信息goos: darwingoarch: amd64BenchmarkNewDummy-8     hell0hell0hell0hell0hell0hell0hell0hell0hell0hell02000000000               0.00 ns/op            0 B/op          0 allocs/opPASSok        0.508s与互斥量情况几乎相同:func BenchmarkNewDummy(b *testing.B) {    one := ""    two := ""    var wg sync.WaitGroup    wg.Add(2)    var mu sync.Mutex    go func() {        mu.Lock()        defer mu.Unlock()        defer wg.Done()        one = "hello"    }()    go func() {        mu.Lock()        defer mu.Unlock()        defer wg.Done()        two = "hello"    }()    wg.Wait()    fmt.Println(one)    fmt.Println(two)}输出:goos: darwingoarch: BenchmarkNewDummy-8     hellohellohellohellohellohellohellohellohellohello2000000000               0.00 ns/op            0 B/op          0 allocs/opPASSok        0.521s内存图看起来几乎相同,但使用 mutext 更大的内存分配,但也没有提供信息:是否可以比较通道和互斥体内存消耗?
查看完整描述

1 回答

?
红糖糍粑

TA贡献1815条经验 获得超6个赞

你做的基准测试是错误的。引用包文档testing:


示例基准函数如下所示:


func BenchmarkHello(b *testing.B) {

    for i := 0; i < b.N; i++ {

        fmt.Sprintf("hello")

    }

}

基准函数必须运行目标代码 bN 次。 在基准执行期间,调整 bN 直到基准函数持续足够长的时间以可靠地计时。


也不要fmt.PrintXX()在基准代码中包含调用,您会扭曲结果。


而是对这些函数进行基准测试:


func newDummy() {

    one := make(chan string, 1)

    two := make(chan string, 1)

    var wg sync.WaitGroup

    wg.Add(2)

    go doWork(&wg, one)

    go doWork(&wg, two)

    wg.Wait()

    <-one

    <-two

}


func doWork(wg *sync.WaitGroup, one chan string) {

    defer wg.Done()

    one <- "hell0"

}


func newDummy2() {

    one, two := "", ""

    var wg sync.WaitGroup

    wg.Add(2)

    var mu sync.Mutex

    go func() {

        mu.Lock()

        defer mu.Unlock()

        defer wg.Done()

        one = "hello"

    }()

    go func() {

        mu.Lock()

        defer mu.Unlock()

        defer wg.Done()

        two = "hello"

    }()

    wg.Wait()

    _, _ = one, two

}

像这样:


func BenchmarkNewDummy(b *testing.B) {

    for i := 0; i < b.N; i++ {

        newDummy()

    }

}


func BenchmarkNewDummy2(b *testing.B) {

    for i := 0; i < b.N; i++ {

        newDummy2()

    }

}

对其进行基准测试:


go test -bench . -benchmem

我得到这样的输出:


BenchmarkNewDummy-4    605662      1976 ns/op     240 B/op      5 allocs/op

BenchmarkNewDummy2-4   927031      1627 ns/op      56 B/op      4 allocs/op

从结果来看,newDummy()平均执行 5 次分配,总计 250 字节。newDummy2()执行 4 次分配,总共 56 个字节。


查看完整回答
反对 回复 2022-05-10
  • 1 回答
  • 0 关注
  • 130 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信