hen*_*dry 5 testing benchmarking go
在测试从 API 调用的数据库过程时,当它按顺序运行时,它似乎在大约 3 秒内始终如一地运行。但是我们注意到,当多个请求同时传入时,这可能需要更长的时间,从而导致超时。我正在尝试将“一次多个请求”案例复制为go test.
我尝试了-parallel 10go test 标志,但时间在 ~28s 是相同的。
我的基准测试功能有问题吗?
func Benchmark_RealCreate(b *testing.B) {
b.ResetTimer()
for n := 0; n < b.N; n++ {
name := randomdata.SillyName()
r := gofight.New()
u := []unit{unit{MefeUnitID: name, MefeCreatorUserID: "user", BzfeCreatorUserID: 55, ClassificationID: 2, UnitName: name, UnitDescriptionDetails: "Up on the hills and testing"}}
uJSON, _ := json.Marshal(u)
r.POST("/create").
SetBody(string(uJSON)).
Run(h.BasicEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
assert.Contains(b, r.Body.String(), name)
assert.Equal(b, http.StatusOK, r.Code)
})
}
}
Run Code Online (Sandbox Code Playgroud)
否则我如何才能实现我所追求的目标?
该-parallel标志不用于在多个实例中并行运行相同的测试或基准测试。
Run Code Online (Sandbox Code Playgroud)-parallel n Allow parallel execution of test functions that call t.Parallel. The value of this flag is the maximum number of tests to run simultaneously; by default, it is set to the value of GOMAXPROCS. Note that -parallel only applies within a single test binary. The 'go test' command may run tests for different packages in parallel as well, according to the setting of the -p flag (see 'go help build').
因此,基本上,如果您的测试允许,您可以使用-parallel并行运行多个不同的测试或基准测试功能,但在多个实例中运行不同的测试或基准测试功能。
一般来说,并行运行多个基准测试函数违背了对一个函数进行基准测试的目的,因为在多个实例中并行运行它通常会扭曲基准测试。
但是,在您的情况下,代码效率不是您要衡量的,而是要衡量的外部服务。所以 Go 的内置测试和基准测试工具并不真正适合。
当然,当我们的其他测试和基准测试运行时,我们仍然可以使用让这个“基准”自动运行的便利,但是您不应该将其强加到传统的基准测试框架中。
首先想到的是使用 for 循环来启动n所有尝试调用可测试服务的 goroutine。这样做的一个问题是,这只能确保n开始时的并发 goroutine,因为随着调用开始完成,其余调用的并发性会越来越少。
为了克服这个问题并真正测试n并发调用,你应该有一个带有n工作器的工作池,并不断地向这个工作池提供作业,确保始终有n并发服务调用。对于工作池实现,请参阅这是 Go 中的惯用工作线程池吗?
所以总而言之,用n工人启动一个工人池,让 goroutine 在任意时间(例如 30 秒或 1 分钟)向它发送作业,并测量(计数)已完成的作业。基准测试结果将是一个简单的除法。
另请注意,仅出于测试目的,甚至可能不需要工作池。您可以只使用循环来启动ngoroutine,但要确保每个启动的 goroutine 不断调用服务,并且在一次调用后不会返回。
vbu*_*ym 6
我是新手,但为什么不尝试创建一个函数并使用标准并行测试运行它呢?
func Benchmark_YourFunc(b *testing.B) {
b.RunParralel(func(pb *testing.PB) {
for pb.Next() {
YourFunc(staff ...T)
}
})
}
Run Code Online (Sandbox Code Playgroud)
您的示例代码混合了多种内容。你为什么assert在那里使用?这不是测试,而是基准。如果assert方法很慢,你的基准也会很慢。
您还将并行执行从代码中移至测试命令中。您应该尝试使用并发来发出并行请求。这里只是一种可能的开始方式:
func executeRoutines(routines int) {
wg := &sync.WaitGroup{}
wg.Add(routines)
starter := make(chan struct{})
for i := 0; i < routines; i++ {
go func() {
<-starter
// your request here
wg.Done()
}()
}
close(starter)
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
https://play.golang.org/p/ZFjUodniDHr
我们在这里启动一些 goroutine,它们等待starter关闭。因此您可以直接在该行之后设置您的请求。该函数会等待所有请求完成,我们使用的是 WaitGroup。
但重要的是:Go 仅支持并发。因此,如果您的系统没有 10 个内核,则 10 个 goroutine 将不会并行运行。因此,请确保您有足够的可用核心。
从这个开始你就可以玩一点了。您可以开始在基准测试中调用此函数。您还可以调整 goroutine 的数量。
| 归档时间: |
|
| 查看次数: |
2560 次 |
| 最近记录: |