0

0

Golang错误处理是否会影响性能

P粉602998670

P粉602998670

发布时间:2026-01-09 15:48:08

|

680人浏览过

|

来源于php中文网

原创

panic/recover 开销远高于普通错误返回,因需栈展开和状态记录,吞吐量可降100倍以上;error接口返回仅指针传递,几乎无成本;defer单次开销纳秒级,但高频滥用会影响性能。

golang错误处理是否会影响性能

panic/recover 的开销远高于普通错误返回

Go 里用 error 接口返回错误(比如 os.Open 返回 (*File, error))几乎无运行时成本,只是指针传递和接口赋值。但一旦触发 panic,运行时需展开、记录 goroutine 状态、构造调用链,开销是数量级差异。

实测在循环中每轮都 panicrecover,吞吐量可能下降 100 倍以上;而正常 if err != nil 判断基本不影响性能。

  • panic 是异常控制流,不是错误处理机制——它本就不该用于可预期的失败场景
  • HTTP handler 中用 panic 捕获空指针然后 recover,看似“兜底”,实际把可控错误变成了高开销路径
  • benchmark 时注意:BenchmarkFoo-8 中混入 recover 会严重污染结果,建议单独测 panic 路径

defer + error 检查本身不拖慢,但 defer 调用次数过多有影响

defer 不是免费的:每次执行都会在当前 goroutine 的 defer 链表上插入一个节点,runtime 需要管理这些延迟调用。但单次 defer 开销极小(纳秒级),真正要注意的是高频小函数里滥用 defer

func bad() error {
    f, err := os.Open("x")
    if err != nil {
        return err
    }
    defer f.Close() // 这里没问题

    for i := 0; i < 10000; i++ {
        defer fmt.Println(i) // 危险:1 万个 defer 节点,内存+调度开销明显
    }
    return nil
}
  • defer 最适合资源清理(文件、锁、数据库连接),不适合替代 if 判断
  • go tool compile -gcflags="-m" 可查看编译器是否将 defer 优化为内联(小函数且无闭包时可能)
  • goroutine 启动时自带 defer 链表,但大量 defer 仍会增加 GC 扫描压力

errors.Is / errors.As 在 Go 1.13+ 的性能代价很小,但别在热循环里用

errors.Iserrors.As 需要遍历错误链(通过 Unwrap()),最坏情况是 O(n) 时间复杂度。不过绝大多数业务错误链很短(1–3 层),实际开销可以忽略。

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

佳蓝点卡销售系统修正版
佳蓝点卡销售系统修正版

该版本面向个人用户及小型数字卡销售商开发,具有操作简捷、功能强大等特点,且安全及稳定性突出修正说明:1、纠正了部分页面的翻页错误;2、纠正了后台统计不能清零的错误;3、纠正了后台商品管理修改后出错以及无法彻底删除的错误;4、纠正了注册时不能检测用户名是否存在的错误;5、纠正了用户无法修改密码的错误;6、新增“更多新闻”;7、新增会员登陆验证码;8、去除多余及

下载

真正要注意的是:别在 QPS 上万的请求内循环调用它们做条件判断。

  • 如果只判断是否是 os.ErrNotExist,直接用 err == os.ErrNotExist 更快(前提是没被 fmt.Errorf 包裹)
  • 自定义错误类型时,实现 Is(error) bool 方法可跳过默认遍历逻辑
  • errors.Unwrap(err) 单次调用成本低,但反复 for err != nil { err = errors.Unwrap(err) } 不如用 errors.Is

error 字符串拼接和 fmt.Errorf 本身有分配,但通常不构成瓶颈

fmt.Errorf("failed to %s: %w", op, err) 会触发字符串格式化和堆分配,比直接返回原 err 多一次内存分配。但在非高频路径(如初始化、配置加载)里,这点开销无关紧要。

真正在意性能时,可考虑预分配或错误池,但绝大多数服务无需为此优化。

  • 避免在日志中间件里对每个请求都 fmt.Errorf("http %d: %w", status, err) —— 直接传原始 error 更轻量
  • 如果错误信息固定,用 var ErrNotFound = errors.New("not found"),零分配
  • errors.Join(Go 1.20+)合并多个 error 会产生新对象,但仅当需要同时暴露多个原因时才用
实际压测中,Go 错误处理本身极少成为性能瓶颈;真正拖慢服务的,往往是错误发生后没及时返回、导致后续无意义计算,或者把错误日志打在 hot path 里反复调用 fmt.Sprint

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

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

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

177

2024.02.23

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

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

226

2024.02.23

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

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

336

2024.02.23

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

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

208

2024.03.05

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

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

388

2024.05.21

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

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

194

2025.06.09

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

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

189

2025.06.10

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

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

191

2025.06.17

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

3

2026.01.09

热门下载

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

精品课程

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

共32课时 | 3.5万人学习

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

共10课时 | 0.8万人学习

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

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