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

Go 中 t-digest 数据结构的线程安全实现?

Go 中 t-digest 数据结构的线程安全实现?

Go
繁花如伊 2022-06-01 18:20:52
我正在尝试在 Go 中运行一个函数的基准测试,如果更多的 goroutine 同时调用它,我怀疑它会减慢速度。我想在基准测试期间捕获函数调用的 P50 和 P95 延迟,例如,使用 ,github.com/influxdata/tdigest如下所示:package mainimport (    "fmt"    "math/rand"    "sync"    "testing"    "time"    "github.com/influxdata/tdigest")func BenchmarkSomething(b *testing.B) {    concurrencies := []int{1, 10, 30}    total := 1000    for _, concurrency := range concurrencies {        b.Run(fmt.Sprintf("concurrency_%d", concurrency), func(b *testing.B) {            td := tdigest.New()            for i := 0; i < b.N; i++ {                send := make(chan struct{}, total)                var wg sync.WaitGroup                for i := 0; i < concurrency; i++ {                    wg.Add(1)                    go func() {                        for range send {                            start := time.Now()                            duration := time.Duration(int64(rand.NormFloat64()*1e6)) + time.Millisecond                            time.Sleep(time.Duration(duration))                            td.Add(float64(time.Since(start)), 1)                        }                    }()                }                for i := 0; i < total; i++ {                    send <- struct{}{}                }                close(send)            }            b.Log("P50 latency:", td.Quantile(0.50))        })    }}但是,如果我尝试运行它,我会收到一个index out of range错误:> go test -bench .goos: darwingoarch: amd64pkg: github.com/kurtpeek/send-closed-channelBenchmarkSomething/concurrency_1-8          panic: runtime error: index out of range我怀疑从多个 goroutine 调用这个函数是不安全的?有没有办法获得线程安全的估计器?
查看完整描述

1 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

在高层次上,我通过将问题分为两个步骤来解决这个问题:将延迟发送到缓冲通道(在这种情况下,所需的缓冲区大小是预先知道的),然后调用td.Add()结果。这避免了并发调用td.Add(),同时仍然实现了在并发设置中测量延迟的预期结果。



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

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号