惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
T
Tenable Blog
D
DataBreaches.Net
GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
腾讯CDC
V
Visual Studio Blog
B
Blog
雷峰网
雷峰网
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
I
InfoQ
M
MIT News - Artificial intelligence
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
The Cloudflare Blog
L
LangChain Blog
MongoDB | Blog
MongoDB | Blog
Vercel News
Vercel News
Cloudbric
Cloudbric
L
Lohrmann on Cybersecurity
博客园 - 司徒正美
T
The Exploit Database - CXSecurity.com
Google DeepMind News
Google DeepMind News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Attack and Defense Labs
Attack and Defense Labs
Martin Fowler
Martin Fowler
SecWiki News
SecWiki News
T
Threat Research - Cisco Blogs
J
Java Code Geeks
Cyberwarzone
Cyberwarzone
Forbes - Security
Forbes - Security
Spread Privacy
Spread Privacy
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
O
OpenAI News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Schneier on Security
Schneier on Security
S
Security @ Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
The Hacker News
The Hacker News
H
Help Net Security
Y
Y Combinator Blog
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tor Project blog
量子位
U
Unit 42
S
SegmentFault 最新的问题
V
V2EX
D
Docker

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes Networking Model & CNI Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Kubernetes - CRI 概述 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes - kube-proxy 代理模式工程优化 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述 微服务中的熔断算法 漏桶算法和令牌桶算法 jsonparser 为什么比标准库的 encoding/json 快 10 倍 ? zap 高性能设计与实现 HTTP Router 算法演进 fastcache 高性能设计与实现 Web 常见的三个安全问题 ants Code Reading Go 线程安全 map 方案选型 布隆过滤器 死锁、活锁、饥饿、自旋锁 sync.Pool Code Reading Go 内存管理概述 Go netpoll Code Reading goroutine 泄漏与检测 time/Timer Code Reading GMP Scheduler Code Reading Go channel 的 15 条规则和底层实现 为什么 Linux “一切皆文件” context.Context Code Reading runtime/HACKING.md Goland 最佳实践 互联网开发与金庸武学 为什么 Redis 6.0 引入多线程模型? Kubernetes 应用最佳实践 - 金丝雀发布 容器中如何正确配置 GOMAXPROCS ? singleflight Code Reading sync.Map Code Reading sync.Cond Code Reading sync.WaitGroup Code Reading sync.RWMutex Code Reading sync.Mutex Code Reading sync.Once Code Reading Go 无锁编程 sync/atomic Code Reading goroutine 交替打印奇偶数 GODEBUG Go 并发模式 Go 汇编 UUID 通用技术选型 Kubernetes 应用最佳实践 - 水平自动伸缩 fasthttp 为什么比标准库 net/http 快 10 倍 ? 技术文章配图指南 ChatGPT 初体验 Docker 网络原理概览 iptables 的五表五链 Kubernetes 应用最佳实践 - 亲和性和污点容忍度 Go 的反射与三大定律 Docker 官方提供的最佳实践 Go 语言内置的设计模式 HTTP1 到 HTTP3 的工程优化 Kubernetes 应用最佳实践 - Sidecar 模式 Kubernetes 应用最佳实践 - init 容器和钩子函数 为什么 recover 必须在 defer 中调用? 为什么 defer 的执行顺序和注册顺序不同? Go map 设计与实现 Go 切片扩容底层实现 Go 语言中的零拷贝 Go Delve 云原生和边缘计算简介 Kubernetes Pod 服务质量等级 Kubernetes 应用最佳实践 - 探针 Kubernetes 应用最佳实践 - 资源请求和限制 CDN 原理 Kubernetes 应用最佳实践 - 开篇 缓存策略和模式 Go 内存模型 Kubernetes 核心概念 软件版本语义化
Go 高性能 Tips
2023-04-10 · via 蛮荆

蛮荆

2023-04-10 Golang 高性能编程

最简单的方法

升级到稳定的最新版本,享受官方升级带来的红利。

常量与变量

  • 多处使用的变量提取为常量
  • 局部变量使用 := 初始化
  • 局部变量 列表型 数据,可以使用数组替代切片

数据类型

  • 切片 初始化时预分配容量
  • map 初始化时预分配容量
  • map 的键类型尽可能选择整型
  • map 记得及时删除过期数据,定期重置稀疏 map
  • 优先使用 []byte 而非 string (标准库和第三方大多数 API 都是 []byte),避免两者之间类型转换,还可以通过 引用机制 进行复用
  • 列表型 元素是稀疏的(例如有很多 0 或者 nil),可以使用 map 作为存储结构
  • map 只有 没有 并且 的分布连续时,可以使用 数组切片 实现
  • 如果 切片 元素是复杂的数据类型,使用 for i, _ := range slice 方式遍历,避免复制元素带来的性能损耗
  • 尽量避免 hot path 上面的内存分配、加锁解锁等操作
  • 尽量使用具体的数据类型而非 any
  • 尽量使用 缓冲通道 而非 非缓冲通道
  • 小对象使用 值传递 ,而非 指针传递
  • 对于非持久性对象,优先分配到栈
  • 大多数情况下,使用指针类型作为方法的 接收者
  • 复杂对象参数传递时传递其指针
  • 复杂对象存储到切片时存储其指针
  • 使用空结构体 struct{} 优化内存
  • 注意 内存对齐

标准库

  • 整数转字符串使用 strconv.Itoa
  • 较长的字符串拼接使用 strings.Builder
  • 使用对象池 sync.Pool 复用对象
  • 循环中使用 time.After 时记得复用
  • 复用 HTTP 链接
  • 使用 sync/atomic 包避免锁操作
  • 使用 IO 缓冲,如 bufio.NewWrite() bufio.NewReader()
  • IO 密集型 场景并发操作
  • 尽可能避免使用 反射
  • 尽可能使用 读写锁 替代 互斥锁
  • 尽可能减小 锁的粒度,使用完成后立即释放
  • hot path 上尽可能避免使用 defer 释放锁
  • hot path 上的 encoding/binary 相关操作可以手动实现,避免标准库实现中的 反射
  • 正则表达式如果多次使用,使用 regexp.Compile() 提前编译完成
  • 使用 runtime.Callers 打印堆栈信息而非 runtime.Stack
  • 使用 singleflight 防止缓存击穿
  • 合理使用 内联优化

备注

笔者在测试上面的 Tips 有效性时,Go 版本为 go1.19 linux/amd64, 这些 Tips 可能随着 Go 版本的变化不再适用,读者遇到具体的性能问题时,应该首先分析具体业务场景,以严格的测试结果为准,切莫按图索骥

扩展阅读

转载申请

本作品采用 知识共享署名 4.0 国际许可协议 进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,商业转载请联系作者获得授权。