0

0

如何在Golang中传递大结构体的性能对比 Go语言值传递与指针传递基准测试

P粉602998670

P粉602998670

发布时间:2026-03-08 11:34:03

|

460人浏览过

|

来源于php中文网

原创

值传递适合小结构体(64字节);基准测试需用go test -bench,禁用内联、稳定gc,并用b.reportallocs检测堆分配。

如何在golang中传递大结构体的性能对比 go语言值传递与指针传递基准测试

Go 中结构体传参:值传递和指针传递到底差多少

差别取决于结构体大小和使用方式。小于 16 字节的小结构体(比如 Point{int, int})值传递通常更快;超过 64 字节后,指针传递几乎总是更优,尤其在频繁调用或嵌套深的场景里。

怎么测出真实差异:用 go test -bench 而不是手写循环

手动计时误差大,且 Go 的编译器可能优化掉未使用的参数或内联简单函数,导致结果失真。基准测试能禁用内联、稳定 GC 状态,并跑足够多轮取平均值。

  • 必须用 func BenchmarkXxx(b *testing.B) 形式,且每次迭代都要调用目标函数
  • 避免在 Benchmark 函数里声明大变量——它会被算进耗时,干扰结构体传参本身的开销
  • b.ReportAllocs() 观察是否意外触发堆分配(值传递大结构体可能逃逸到堆)
  • 示例片段:
    func BenchmarkStructValue(b *testing.B) {
        s := BigStruct{...}
        for i := 0; i < b.N; i++ {
            consumeValue(s) // 注意:这里 s 是复制的
        }
    }

    go tool compile -S 看汇编:确认结构体真被复制了没

    Go 编译器对小结构体常做寄存器传参或栈内紧凑拷贝,对大结构体则生成显式的 MOVQ/MOVO 块拷贝指令。不看汇编,光靠“结构体很大”就加 *,反而可能破坏 CPU 缓存局部性。

    Veed AI Voice Generator
    Veed AI Voice Generator

    Veed推出的AI语音生成器

    下载
    • 运行 go tool compile -S main.go | grep -A5 'consumeValue',找是否有大块内存移动指令
    • 如果函数被内联,汇编里看不到调用,需加 //go:noinline 注释强制不内联
    • 32 字节以内的结构体,在 amd64 上大概率走 AX/DX/R8/R9 寄存器传,基本无额外开销

    别只盯着“传什么”,先看“怎么用”:逃逸分析才是关键分水岭

    即使你写了值传递,如果结构体字段被取地址、传给 goroutine、或作为接口值存储,它就会逃逸到堆——这时复制成本反而是次要的,GC 压力和内存延迟才真正拖慢性能。

    立即学习go语言免费学习笔记(深入)”;

    • go run -gcflags="-m -l" main.go 检查结构体是否逃逸
    • 指针传递不等于一定上堆:栈上分配的结构体,其地址仍可安全传指针(只要生命周期可控)
    • 常见坑:把大结构体直接塞进 map[string]BigStruct,读写时会反复复制;换成 map[string]*BigStruct 后,注意 nil 检查和生命周期管理
    实际项目里,结构体要不要加 *,得先看它是否逃逸、是否高频调用、是否跨 goroutine 共享。盲目统一用指针,可能让小结构体失去寄存器优化,还增加一次解引用;死守值传递,又可能在日志、序列化等场景里引发大量内存拷贝。这两条路的边界,不在字节数上,而在逃逸分析结果和 profile 数据里。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

210

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

246

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

355

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

407

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

470

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

200

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1377

2025.06.17

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

23

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 6万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号