当前位置: 首页 > news >正文

Go进阶之性能测试原理

1.数据结构:

源码位置:src/testing/benchmark.go:B

type B struct { common importPath string // import path of the package containing the benchmark bstate *benchState N int previousN int // number of iterations in the previous run previousDuration time.Duration // total duration of the previous run benchFunc func(b *B) benchTime durationOrCountFlag bytes int64 missingBytes bool // one of the subbenchmarks does not have bytes set. timerOn bool showAllocResult bool result BenchmarkResult parallelism int // RunParallel creates parallelism*GOMAXPROCS goroutines // The initial states of memStats.Mallocs and memStats.TotalAlloc. startAllocs uint64 startBytes uint64 // The net total of this test after being run. netAllocs uint64 netBytes uint64 // Extra metrics collected by ReportMetric. extra map[string]float64 // For Loop() to be executed in benchFunc. // Loop() has its own control logic that skips the loop scaling. // See issue #61515. loopN int }

1).基础标识与调度:

importPath:包导入路径.

bstate:状态测试管理器.

benchFunc:测试函数.

2).循环控制:

N:循环执行次数.

previousN:上一轮循环次数.

loopN:loop专用循环数.

3).耗时统计:

benchTime:测试目标耗时. 控制基准测试的最小总耗时(默认 1s,可通过-

benchtime调整,如-benchtime=5s-benchtime=100x)

previousDuration:上一轮总耗时.

timerOn:计时器开关.

4).内存或字节统计:

bytes:每次迭代处理的字节数.

missingBytes:测试字节数缺失标记.

startAllocs:内存分布次数初始值.

startBytes:内存分配字节初始值.

netAllocs:总分配次数.

netBytes:总分配字节数.

5).并行控制:

parallelism:并行度.

6).结果与输出:

result:基准测试结果.

showAllocResult:内存结果显示标记.

extra:自定义指标.

7).通用能力:

common:通用测试能力.

2.启动计时.B.StartTimer():

源码位置:src/testing/benchmark.go

func (b *B) StartTimer() { if !b.timerOn { runtime.ReadMemStats(&memStats) b.startAllocs = memStats.Mallocs b.startBytes = memStats.TotalAlloc b.start = highPrecisionTimeNow() b.timerOn = true } }

StartTimer()负责启动计时并初始化内存相关计数.测试执行时会自动调用.一般不需

要用户启动.

流程图:

3.停止计时.B.StopTimer():

源码位置:src/testing/benchmark.go

StopTimer()负责停止计时.并累加相应的值.

// StopTimer stops timing a test. This can be used to pause the timer // while performing steps that you don't want to measure. func (b *B) StopTimer() { if b.timerOn { b.duration += highPrecisionTimeSince(b.start) runtime.ReadMemStats(&memStats) b.netAllocs += memStats.Mallocs - b.startAllocs b.netBytes += memStats.TotalAlloc - b.startBytes b.timerOn = false } }

需要注意的是.StopTimer()并不一定是测试结束.一个测试中有可能有多个统计阶

段.所以统计值是累加的.

流程图:

4.重置计时.B.ResetTimer():

ResetTimer()用于重置计时器.相应的也会把其他统计值也重置.

源码位置:src/testing/benchmark.go

// ResetTimer zeroes the elapsed benchmark time and memory allocation counters // and deletes user-reported metrics. // It does not affect whether the timer is running. func (b *B) ResetTimer() { if b.extra == nil { // Allocate the extra map before reading memory stats. // Pre-size it to make more allocation unlikely. b.extra = make(map[string]float64, 16) } else { clear(b.extra) } if b.timerOn { runtime.ReadMemStats(&memStats) b.startAllocs = memStats.Mallocs b.startBytes = memStats.TotalAlloc b.start = highPrecisionTimeNow() } b.duration = 0 b.netAllocs = 0 b.netBytes = 0 }

流程图:

5.SetBytes():

源码位置:src/testing/benchmark.go

// SetBytes records the number of bytes processed in a single operation. // If this is called, the benchmark will report ns/op and MB/s. func (b *B) SetBytes(n int64) { b.bytes = n }

流程图:

核心公式:

// 总处理字节数 = 单次迭代字节数 × 总迭代次数

totalBytes = b.bytes × b.N

// 总耗时(秒)= 总有效耗时(纳秒) / 10^9

totalSeconds = b.duration / 1e9

// 吞吐量(MB/s)= 总处理字节数(MB) / 总耗时(秒)

// 注:1MB = 1024×1024 = 1048576 字节

throughputMBps = (totalBytes / 1048576) / totalSeconds

测试代码:

func BenchmarkSetBytes(b *testing.B) { b.SetBytes(1024 * 1024) for i := 0; i < b.N; i++ { time.Sleep(1 * time.Second) } }

执行结果:

6.runN():

源码位置:src/testing/benchmark.go

// runN runs a single benchmark for the specified number of iterations. func (b *B) runN(n int) { benchmarkLock.Lock() defer benchmarkLock.Unlock() ctx, cancelCtx := context.WithCancel(context.Background()) defer func() { b.runCleanup(normalPanic) b.checkRaces() }() // Try to get a comparable environment for each run // by clearing garbage from previous runs. runtime.GC() b.resetRaces() b.N = n b.loopN = 0 b.ctx = ctx b.cancelCtx = cancelCtx b.parallelism = 1 b.ResetTimer() b.StartTimer() b.benchFunc(b) b.StopTimer() b.previousN = n b.previousDuration = b.duration }

流程图:

7.内存统计:

源码位置:src/testing/benchmark.go

// BenchmarkResult contains the results of a benchmark run. type BenchmarkResult struct { N int // The number of iterations. T time.Duration // The total time taken. Bytes int64 // Bytes processed in one iteration. MemAllocs uint64 // The total number of memory allocations. MemBytes uint64 // The total number of bytes allocated. // Extra records additional metrics reported by ReportMetric. Extra map[string]float64 }

N:最终执行的迭代次数.

T:总耗时.

Bytes:单词迭代处理的字节数.

MemAllocs:总内存分配次数.

MemBytes:总内存分配字节数.

Extra:自定义性能指标.

生成流程(关联runN):

AllocsPerOp()函数:

// AllocsPerOp returns the "allocs/op" metric, // which is calculated as r.MemAllocs / r.N. func (r BenchmarkResult) AllocsPerOp() int64 { if v, ok := r.Extra["allocs/op"]; ok { return int64(v) } if r.N <= 0 { return 0 } return int64(r.MemAllocs) / int64(r.N) }

流程图:

AllocedBytesPerOp()函数:

// AllocedBytesPerOp returns the "B/op" metric, // which is calculated as r.MemBytes / r.N. func (r BenchmarkResult) AllocedBytesPerOp() int64 { if v, ok := r.Extra["B/op"]; ok { return int64(v) } if r.N <= 0 { return 0 } return int64(r.MemBytes) / int64(r.N) }

流程图:

语雀地址https://www.yuque.com/itbosunmianyi/xg8vfe?

《Go.》 密码:xbkk 欢迎大家访问.提意见.

岁月悠悠.

如果大家喜欢我的分享的话.可以关注我的微信公众号

念何架构之路

http://www.jsqmd.com/news/396926/

相关文章:

  • UCB-CS170-算法笔记-全-
  • SpringCloud 多模块下引入独立bom模块的正确架构方案
  • UCB-CS186-数据库导论笔记-全-
  • UIUC-CS225-数据结构中文笔记-全-
  • 液氩采购指南:如何选择可靠的直销厂家,液氧/制氮机/真空管/液氩/液氮/制氧机/储罐/二氧化碳,液氩公司口碑推荐榜 - 品牌推荐师
  • 华盛顿大学-CSE331-软件设计与实现讲座笔记-全-
  • 滑铁卢-CS452-实时编程讲座笔记-全-
  • 康奈尔-CS3110-数据结构与函数式编程讲义-全-
  • 拖延症福音 10个AI论文写作软件测评:自考毕业论文+开题报告必备工具推荐
  • 携程旅行机票抓取
  • P3121 [USACO15FEB] Censoring G
  • 2026年国内诚信的截止阀实力厂家哪家强,锻钢闸阀/通风蝶阀/V型球阀/锻钢截止阀/蝶式止回阀,截止阀企业联系方式 - 品牌推荐师
  • 携程旅行 参数分析
  • 2026年谷歌/google独立站优化代运营外贸推广公司/服务商深度测评榜单:这5家值得重点关注! - 深圳昊客网络
  • 告别Hyprland/Niri键鼠共享难题:Pynergy —— 为 Wayland 设计的 Synergy 兼容客户端
  • 看完就会:MBA专属降AI率工具,千笔·专业降AIGC智能体 VS 灵感风暴AI
  • php代碼審計(危險函數了解與)
  • php代碼審計(危險函數了解與pikachu靶場分析)
  • 交稿前一晚!AI论文软件 千笔ai写作 VS 锐智 AI,研究生高效写作神器!
  • 格式总出错?千笔·专业论文写作工具,实力封神的AI论文软件
  • 小白救星!降AIGC网站 千笔 VS 笔捷Ai,专科生专属神器!
  • 王阳明心学05
  • 天虹提货券回收避坑指南 - 京顺回收
  • 建议收藏|8个降AIGC平台深度测评,本科生降AI率必备指南
  • 告别熬夜改稿!6款免费AI论文工具,一键生成初稿超省力 - 麟书学长
  • 科研党收藏!10个AI论文网站测评:本科生毕业论文写作必备工具推荐
  • 2026国内做得好的双片钉箱机公司,排行榜单告诉你,双片钉箱机实力厂家优质品牌榜单更新 - 品牌推荐师
  • 用过才敢说 9个AI论文软件测评:MBA毕业论文+科研写作必备工具推荐
  • Python基于Vue的 网络书店管理系统django flask pycharm
  • Python基于Vue的中医药文献管理系统 django flask pycharm