-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 更大的内存分配,但也没有提供信息: 在此处输入图像描述在此处输入图像描述

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

4

1 回答 1

2

你做的基准测试是错误的。引用包文档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 个字节。

于 2020-01-28T09:06:31.793 回答