Go高性能代码的核心是让编译器和运行时“省力”:少分配、少逃逸、少同步、少抽象;高频路径预分配切片、复用sync.Pool、避免隐式分配、小结构体传值、合理选用map/slice。

Go 高性能代码不是靠堆砌并发或炫技实现的,而是由一连串克制、可验证的选择构成:少分配、少逃逸、少同步、少抽象。核心原则就一条:让编译器和运行时尽可能“省力”。
避免不必要的内存分配
每次 make、new、字符串拼接(+)、fmt.Sprintf 都可能触发堆分配,而 GC 压力会直接拖慢吞吐。高频路径上尤其敏感。
- 循环内不要反复
make([]int, 10),改用预分配后复用:s := make([]int, 0, 10),再用s = s[:0]清空 - JSON 解析等场景,优先用
sync.Pool复用bytes.Buffer或结构体指针,而非每次都&MyStruct{} - 避免隐式分配:返回局部切片(如
return data[10:20])可能造成底层数组逃逸;若原切片生命周期短,考虑复制:copy(dst, src[10:20])
慎用指针传递大值类型
Go 中 slice、map、chan、func 本身已是引用类型,传值开销极小;但传 *[]T 或 *struct{...} 反而可能引发额外解引用、阻碍内联,甚至导致逃逸分析失败。
- Bad:
func process(s *[]byte) { ... }—— 强制分配堆内存存储 slice 头 - Good:
func process(s []byte) { ... }—— slice 是三个字长的值,栈上传递高效 - 结构体小于 32 字节(如
type Point struct{ X, Y int }),通常建议传值;大于则按需传指针,但要确认是否真需要修改原值
用对数据结构,别为“看起来整洁”牺牲性能
map 查找是 O(1),slice 查找是 O(n),但 map 的内存占用、哈希计算、扩容成本远高于 slice。选型必须结合访问模式和数据规模。
ThinkPHP是一个快速、简单的基于MVC和面向对象的轻量级PHP开发框架,遵循Apache2开源协议发布,从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,尤其注重开发体验和易用性,并且拥有众多的原创功能和特性,为WEB应用开发提供了强有力的支持。 3.2版本则在原来的基础上进行一些架构的调整,引入了命名空间支持和模块化的完善,为大型应用和模块化开发提供了更多的便利。
立即学习“go语言免费学习笔记(深入)”;
- 键集固定且数量少([]struct{key string; value int} + 线性查找更省内存、缓存友好
- 需要频繁增删 key?
map[string]int合理;但只读场景下,考虑预排序 +sort.SearchStrings二分查找,避免 map 的哈希扰动 - 别用
map[interface{}]interface{}存简单键值——类型断言开销大,且无法静态推导,易逃逸
goroutine 不是银弹,控制并发粒度比“开一堆”更重要
每 goroutine 至少占用 2KB 栈空间,调度器需维护其状态。无节制启动会导致 GOMAXPROCS 竞争、上下文切换飙升、GC 扫描压力倍增。
- 避免在循环里直接
go doWork(i)—— i 可能被所有 goroutine 共享(经典闭包捕获 bug),且无并发上限 - 用 worker pool 模式:固定数量 goroutine 消费带缓冲的
chan,例如jobs := make(chan Task, 128) - I/O 密集任务(如 HTTP 请求)可适度放宽并发数;CPU 密集任务应严格限制,通常 ≤
GOMAXPROCS
最容易被忽略的一点是:**性能优化必须以 profile 为前提**。不跑 go test -benchmem、不看 pprof 的火焰图,所有“我觉得这里慢”的判断都是猜测。一个 sync.Pool 用错位置,可能比不用还慢。










