美文网首页
Benchmark基准测试

Benchmark基准测试

作者: 五岁小孩 | 来源:发表于2024-03-17 14:11 被阅读0次

    压测Benchmark基准测试 - Jxy 博客

    Benchmark基准测试

    简单基测

    当我们尝试去优化代码的性能时,首先得知道当前的性能怎么样。

    Go 语言标准库内置的 testing 测试框架提供了基准测试(benchmark)的能力,能让我们很容易地对某一段代码进行性能测试。

    性能测试受环境的影响很大,为了保证测试的可重复性,在进行性能测试时,尽可能地保持测试环境的稳定。

    • 机器处于闲置状态,测试时不要执行其他任务,也不要和其他人共享硬件资源。
    • 机器是否关闭了节能模式,一般笔记本会默认打开这个模式,测试时关闭。
    • 避免使用虚拟机和云主机进行测试,一般情况下,为了尽可能地提高资源的利用率,虚拟机和云主机 CPU 和内存一般会超分配,超分机器的性能表现会非常地不稳定。

    参考:https://geektutu.com/post/hpg-benchmark.html

    Benchmark是如何工作的

    单元测试:

    • 运行当前package内的所有用例:go test 【包名】或 go test .
    • 递归执行当前目录下所有用例:go test ./... 或 go test 【目录名】/...
    • 运行指定文件单元测试: go test -v [单元测试文件]. // 如 go test -v foo_test.go
    • 运行指定单元测试用例:go test -v [单元测试文件] -run [单元测试函数]. //如 go test -v foo_test.go -run TestFoo
    • 压测:go test -bench .
    执行参数 简介 备注
    -bench=‘Fib$’ 可传入正则,匹配用例 如只运行以 Fib 结尾的 benchmark 用例
    -cpu=2,4 可改变 CPU 核数 GOMAXPROCS,CPU核数,默认机器的核数
    -benchtime=5s<br />-benchtime=50x 可指定执行时间或具体次数 benchmark 的默认时间是 1s,决定了b.N的次数,测试时间<br />-benchtime的值除了是时间外,还可以是具体的次数。<br />例如,执行 30 次可以用-benchtime=30x
    -count=3 可设置 benchmark 轮数 参数可以用来设置 benchmark 的轮数,默认是1轮
    -benchmem 可查看内存分配量和分配次数 参数可以度量内存分配的次数,添加此参数后会在结果之后显示 n allocs/op <br /> 也就是内存分配了n次,m B/op,<br />总共分配了 m 字节8003641 B/op == 8 003 641 B=7.63M
    -cpuprofile=./cpu.prof 生成CPU性能分析 执行 CPU profiling,并把结果保存在 cpu.prof
    -memprofile=./mem.prof 生成内存性能分析 执行 Mem profiling,并把结果保存在 cpu.prof 文件中
    import (
        "math/rand"
        "testing"
        "time"
    )
    
    func generateWithCap(n int) []int {
        rand.Seed(time.Now().UnixNano())
        nums := make([]int, 0, n)
        for i := 0; i < n; i++ {
            nums = append(nums, rand.Int())
        }
        return nums
    }
    
    func generate(n int) []int {
        rand.Seed(time.Now().UnixNano())
        nums := make([]int, 0)
        for i := 0; i < n; i++ {
            nums = append(nums, rand.Int())
        }
        return nums
    }
    
    func BenchmarkGenerateWithCap(b *testing.B) {
        for n := 0; n < b.N; n++ {
            generateWithCap(1000000)
        }
    }
    
    func BenchmarkGenerate(b *testing.B) {
        for n := 0; n < b.N; n++ {
            generate(1000000)
        }
    }
    
    
    $ go test -bench='Generate' -benchmem  -cpu=2,4,8  .    // 执行的指令
    
    goos: darwin   // 操作系统
    goarch: arm64  // cpu处理器
    pkg: itxj.com/xj-utils/utils/algorithm   // 测试执行所在的包
    BenchmarkGenerateWithCap-2            82          13937680 ns/op         8003584 B/op           1 allocs/op
    BenchmarkGenerateWithCap-4            84          14083593 ns/op         8003595 B/op           1 allocs/op
    BenchmarkGenerateWithCap-8            85          13938689 ns/op         8003616 B/op           1 allocs/op
    BenchmarkGenerate-2                   68          15586489 ns/op        45188365 B/op           40 allocs/op
    BenchmarkGenerate-4                   70          15646168 ns/op        45188417 B/op           40 allocs/op
    BenchmarkGenerate-8                   73          15948826 ns/op        45188464 B/op           41 allocs/op
    // 执行测试函数所用CPU核数               执行次数   每次花费时间左移动9位为秒s 每次分配内存字节B左移6位为m  每次分配内存次数
    // 如用2核CPU执行BenchmarkGenerate函数               0014083593ns=0.014s    8003584B=7.9m          
    
    PASS
    ok      itxj.com/xj-utils/utils/algorithm       7.682s    // 总共执行耗时
    
    结果参数 简介
    b.N benchmark的次数b.N,默认是-benchtime=1s内执行的次数,<br />b.N 从 -benchtime=1s开始,如果该用例能够在 1s 内完成,<br />b.N 的值大概以 1, 2, 3, 5, 10, 20, 30, 50, 100 这样的序列递增,越到后面,增加得越快
    goos 操作系统
    goarch cpu处理器
    pkg 所在的包
    BenchmarkGenerate-2<br />BenchmarkGenerate-4<br />BenchmarkGenerate-8 【测试函数名】-【cpu核数】BenchmarkGenerate-2,<br />表示使用2核CPU执行BenchmarkGenerate测试函数
    ns/op 每次耗时多少毫秒
    B/op 每次分配内存多少字节Bytes
    allocs/op 每次分配多少次内存

    运行测试用例:

    func fib(n int) int {
        if n == 0 || n == 1 {
            return n
        }
        return fib(n-2) + fib(n-1)
    }
    
    import "testing"
    
    func BenchmarkFib(b *testing.B) {
        for n := 0; n < b.N; n++ {
            fib(30) // run fib(30) b.N times
        }
    }
    

    提高准确度

    内存分配情况

    不同输入复杂度测试

    其他注意事项

    • ResetTimer
    • StopTimer
    • StartTimer

    相关文章

      网友评论

          本文标题:Benchmark基准测试

          本文链接:https://www.haomeiwen.com/subject/stgozdtx.html