首页 > 其他分享 >Go语言精进之路读书笔记第46条——为被测对象建立性能基准

Go语言精进之路读书笔记第46条——为被测对象建立性能基准

时间:2024-03-10 20:24:49浏览次数:31  
标签:tls 读书笔记 46 mu go test atomic Go round

46.1 性能基准测试在Go语言中是“一等公民”

性能基准测试在Go语言中和普通的单元测试一样被原生支持的,得到的是“一等公民”的待遇。

我们可以像对普通单元测试那样在*_test.go文件中创建被测对象的性能基准测试,每个以Benchmark前缀开头的函数都会被当作一个独立的性能基准测试。

46.2 顺序执行和并行执行的性能基准测试

#通过-benchtime手动指定b.N的值
go test -v -benchtime 5x -bench . sequential_test.go

#通过-count手动指定执行次数
go test -v -count 2 -bench . sequential_test.go

#通过-cpu手动指定GOMAXPROCS
go test -v -bench . paralell_test.go -cpu 2,4,8
go test -v -bench . paralell_test.go -cpu=2

1.顺序执行

var (
    m     map[int64]struct{} = make(map[int64]struct{}, 10)
    mu    sync.Mutex
    round int64 = 1
)

func BenchmarkSequential(b *testing.B) {
    fmt.Printf("\ngoroutine[%d] enter BenchmarkSequential: round[%d], b.N[%d]\n",
        tls.ID(), atomic.LoadInt64(&round), b.N)
    defer func() {
        atomic.AddInt64(&round, 1)
    }()

    for i := 0; i < b.N; i++ {
        mu.Lock()
        _, ok := m[round]
        if !ok {
            m[round] = struct{}{}
            fmt.Printf("goroutine[%d] enter loop in BenchmarkSequential: round[%d], b.N[%d]\n",
                tls.ID(), atomic.LoadInt64(&round), b.N)
        }
        mu.Unlock()
    }
    fmt.Printf("goroutine[%d] exit BenchmarkSequential: round[%d], b.N[%d]\n",
        tls.ID(), atomic.LoadInt64(&round), b.N)
}

2.并行执行

var (
    m     map[int64]int = make(map[int64]int, 20)
    mu    sync.Mutex
    round int64 = 1
)

func BenchmarkParalell(b *testing.B) {
    fmt.Printf("\ngoroutine[%d] enter BenchmarkParalell: round[%d], b.N[%d]\n",
        tls.ID(), atomic.LoadInt64(&round), b.N)
    defer func() {
        atomic.AddInt64(&round, 1)
    }()

    b.RunParallel(func(pb *testing.PB) {
        id := tls.ID()
        fmt.Printf("goroutine[%d] enter loop func in BenchmarkParalell: round[%d], b.N[%d]\n", tls.ID(), atomic.LoadInt64(&round), b.N)
        for pb.Next() {
            mu.Lock()
            _, ok := m[id]
            if !ok {
                m[id] = 1
            } else {
                m[id] = m[id] + 1
            }
            mu.Unlock()
        }

        mu.Lock()
        count := m[id]
        mu.Unlock()

        fmt.Printf("goroutine[%d] exit loop func in BenchmarkParalell: round[%d], loop[%d]\n", tls.ID(), atomic.LoadInt64(&round), count)
    })

    fmt.Printf("goroutine[%d] exit BenchmarkParalell: round[%d], b.N[%d]\n",
        tls.ID(), atomic.LoadInt64(&round), b.N)
}

46.3 使用性能基准比较工具

benchcmp已废弃,官方推荐用经过统计学方法处理的benchstat。

46.4 排除额外干扰,让基准测试更精确

使用testing.B提供的定时器操作方法排除额外干扰,让基准测试更精确,但不要在RunParallel中使用ResetTimer、StartTimer、StopTimer,因为它们具有全局副作用。

标签:tls,读书笔记,46,mu,go,test,atomic,Go,round
From: https://www.cnblogs.com/brynchen/p/18064720

相关文章

  • Go语言精进之路读书笔记第48条——使用expvar输出度量数据,辅助定位性能瓶颈点
    48.1expvar包的工作原理Go标准库中的expvar包提供了一种输出应用内部状态信息的标准化方案,这个方案标准化了以下三方面内容:数据输出接口形式输出数据的编码格式用户自定义性能指标的方法import(_"expvar""fmt""net/http")funcmain(){http.Hand......
  • Go语言精进之路读书笔记第47条——使用pprof对程序进行性能剖析
    47.1pprof的工作原理1.采样数据类型(1)CPU数据(2)堆内存分配数据(3)锁竞争数据(4)阻塞时间数据2.性能数据采集的方式(1)通过性能基准测试进行数据采集gotest-bench.xxx_test.go-cpuprofile=cpu.profgotest-bench.xxx_test.go-memprofile=mem.profgotes......
  • Go语言精进之路读书笔记第49条——使用Delve调试Go代码
    49.1关于调试,你首先应该知道的几件事1.调试前,首先做好心理准备2.预防bug的发生,降低bug的发生概率(1)充分的代码检查(2)为调试版添加断言(3)充分的单元测试(4)代码同级评审3.bug的原因定位和修正(1)收集“现场数据”(2)定位问题所在(3)修正并验证49.2Go调试工......
  • Django进阶之路由层和视图层
    Django的路由系统【1】什么是URL配置(URLconf)URL调度器|Django文档|Django(djangoproject.com)URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个U......
  • Django基础
    【一】web框架web框架本质上可以看成是一个功能强大的socket服务端,用户的浏览器可以看成是拥有可视化界面的socket客户端。两者通过网络请求实现数据交互,从架构层面上先简单的将Web框架看做是对前端、数据库的全方位整合【二】手撸web框架【1】原始版本(1)服务端#[一]......
  • Django入门
    Django入门启动django项目之后如何添加更多的功能回想自己编写的web框架如果要添加功能就去urls.py和views.py【1】添加URL映射在项目的urls.py文件中,通过导入相应的应用(app)及其视图函数,并使用path()或include()函数来定义URL映射规则。例如,如果要在名为"myap......
  • Go语言VSCode开发环境配置
    最近学习Golang,先把开发环境配置好。一、安装Go语言开发包https://golang.google.cn/dl/ 按步骤安装即可,安装完成后需要设置Windows环境变量 配置好,做个测试二、VSCodeGolang开发环境配置vscode安装go插件时,由于各种原因,在安装插件时总是失败,所以先执行以下操作:在......
  • RGI 德国Real Good Idea 流量计 Flocon21
    ProductspecificationEvaluationunitforflowmeasurementsystembasedonmicrowaves DescriptionThe evaluationcomputerFLOCON21forms,togetherwithoneofthesensorsDR-xxx,acontactlessflowmeasurementsystemformanyapplicationsinthe......
  • golang开发_goroutine在项目中的使用姿势
    很多初级的Gopher在学习了goroutine之后,在项目中其实使用率不高,尤其一些跨语言过来的人,对并发编程理解不深入,可能很多人只知道gofunc(),或者掌控不够,谨慎一些,尽量少使用或者不使用,用的话就是gofunc(),主要列一下我们这边的主要使用方法。goroutine在项目中的使用方法看一下样......
  • golang结构体
    在Go语言中,结构体(Struct)是一种用户定义的数据类型,用于组合多个不同类型的字段,每个字段可以是任意的基本类型或其他结构体类型。结构体是一种复合数据类型,用于组织和存储相关的数据。以下是结构体的一些基本概念和用法:1.定义结构体//定义一个结构体typePersonstruct{Firs......