如何基准测试通道/互斥锁的内存消耗/分配?

问题描述 投票:-1回答:1

[我尝试使用一个值的通道与使用互斥锁进行比较。频道示例:

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: darwin
goarch: amd64
BenchmarkNewDummy-8     hell0
hell0
hell0
hell0
hell0
hell0
hell0
hell0
hell0
hell0
2000000000               0.00 ns/op            0 B/op          0 allocs/op
PASS
ok        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: darwin
goarch: 
BenchmarkNewDummy-8     hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
2000000000               0.00 ns/op            0 B/op          0 allocs/op
PASS
ok        0.521s

内存图看起来几乎相同,但是mutext的内存分配更大,但是信息也不多:enter image description hereenter image description here

是否可以比较通道和互斥锁的内存消耗?

go profiling benchmarking pprof
1个回答
2
投票

您做基准测试错误。引用testing的软件包文档:

示例基准函数如下所示:

testing

基准功能必须运行目标代码b.N次。在基准执行期间,将调整b.N,直到基准功能持续足够长的时间以可靠地计时。

也不要在基准代码中包含func BenchmarkHello(b *testing.B) { for i := 0; i < b.N; i++ { fmt.Sprintf("hello") } } 调用,您会扭曲结果。

将这些功能标为基准:

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 平均执行5个分配,总共250个字节。 newDummy()执行4个分配,总共56个字节。

© www.soinside.com 2019 - 2024. All rights reserved.