Changes: - Renamed all 10 Golang files from English to Chinese names - Created 00-项目概述/项目概述.md with comprehensive project overview - Created 08-算法与数据结构/算法与数据结构学习指南.md with detailed learning guide - Created 12-面试技巧/面试准备进度.md with progress tracking - Added .obsidian configuration for better markdown editing - Updated Claude.MD with Chinese filename rule Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
287 lines
4.2 KiB
Markdown
287 lines
4.2 KiB
Markdown
# Golang 性能优化
|
||
|
||
## 问题
|
||
|
||
1. Go 的性能分析工具有哪些?
|
||
2. pprof 如何使用?
|
||
3. 如何减少内存分配?
|
||
4. 如何优化 CPU 性能?
|
||
5. 如何进行并发性能优化?
|
||
6. Go 的性能优化最佳实践是什么?
|
||
|
||
---
|
||
|
||
## 标准答案
|
||
|
||
### 1. 性能分析工具
|
||
|
||
#### **pprof(CPU 和内存分析)**
|
||
|
||
```bash
|
||
# CPU 性能分析
|
||
go test -cpuprofile=cpu.prof -bench .
|
||
|
||
# 内存分析
|
||
go test -memprofile=mem.prof -bench .
|
||
|
||
# 可视化
|
||
go tool pprof -http=:8080 cpu.prof
|
||
```
|
||
|
||
---
|
||
|
||
#### **trace**
|
||
|
||
```go
|
||
import (
|
||
"os"
|
||
"runtime/trace"
|
||
)
|
||
|
||
func main() {
|
||
f, _ := os.Create("trace.out")
|
||
defer f.Close()
|
||
|
||
trace.Start(f)
|
||
defer trace.Stop()
|
||
|
||
// 程序逻辑
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. pprof 使用
|
||
|
||
#### **CPU 分析**
|
||
|
||
```bash
|
||
# 生成 CPU profile
|
||
go test -cpuprofile=cpu.prof -bench=.
|
||
|
||
# 查看
|
||
go tool pprof cpu.prof
|
||
|
||
# 列出 top 函数
|
||
go tool pprof -top cpu.prof
|
||
|
||
# 可视化
|
||
go tool pprof -http=:8080 cpu.prof
|
||
```
|
||
|
||
---
|
||
|
||
#### **内存分析**
|
||
|
||
```bash
|
||
# 生成 heap profile
|
||
go test -memprofile=heap.prof -bench=.
|
||
|
||
# 查看
|
||
go tool pprof heap.prof
|
||
|
||
# 查看内存分配
|
||
go tool pprof -alloc_space heap.prof
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 减少内存分配
|
||
|
||
#### **1. 使用 sync.Pool**
|
||
|
||
```go
|
||
var bufPool = sync.Pool{
|
||
New: func() interface{} {
|
||
return make([]byte, 1024)
|
||
},
|
||
}
|
||
|
||
func process(data []byte) {
|
||
buf := bufPool.Get().([]byte)
|
||
defer bufPool.Put(buf)
|
||
|
||
copy(buf, data)
|
||
// ...
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### **2. 预分配容量**
|
||
|
||
```go
|
||
// ❌ 多次扩容
|
||
var s []int
|
||
for i := 0; i < 1000; i++ {
|
||
s = append(s, i)
|
||
}
|
||
|
||
// ✅ 预分配
|
||
s := make([]int, 0, 1000)
|
||
for i := 0; i < 1000; i++ {
|
||
s = append(s, i)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4. CPU 性能优化
|
||
|
||
#### **1. 减少系统调用**
|
||
|
||
```go
|
||
// ❌ 多次系统调用
|
||
var b bytes.Buffer
|
||
for i := 0; i < 1000; i++ {
|
||
b.WriteString(strconv.Itoa(i))
|
||
}
|
||
|
||
// ✅ 批量写入
|
||
var b bytes.Buffer
|
||
for i := 0; i < 1000; i++ {
|
||
b.WriteString(strconv.Itoa(i))
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### **2. 避免不必要的拷贝**
|
||
|
||
```go
|
||
// ❌ 拷贝
|
||
func process(data []byte) {
|
||
copy := make([]byte, len(data))
|
||
copy(copy, data)
|
||
// ...
|
||
}
|
||
|
||
// ✅ 使用切片
|
||
func process(data []byte) {
|
||
sub := data[10:20]
|
||
// ...
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 5. 并发性能优化
|
||
|
||
#### **1. 使用 Worker Pool**
|
||
|
||
```go
|
||
func worker(id int, jobs <-chan int, results chan<- int) {
|
||
for j := range jobs {
|
||
results <- j * j
|
||
}
|
||
}
|
||
|
||
func main() {
|
||
jobs := make(chan int, 100)
|
||
results := make(chan int, 100)
|
||
|
||
// 启动 4 个 worker
|
||
for i := 0; i < 4; i++ {
|
||
go worker(i, jobs, results)
|
||
}
|
||
|
||
// 发送任务
|
||
for i := 0; i < 100; i++ {
|
||
jobs <- i
|
||
}
|
||
close(jobs)
|
||
|
||
// 收集结果
|
||
for i := 0; i < 100; i++ {
|
||
<-results
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### **2. 减少 Lock 竞争**
|
||
|
||
```go
|
||
// ❌ 全局锁
|
||
var mu sync.Mutex
|
||
|
||
func process(id int) {
|
||
mu.Lock()
|
||
defer mu.Unlock()
|
||
// ...
|
||
}
|
||
|
||
// ✅ 分片锁
|
||
var mu [16]sync.Mutex
|
||
|
||
func process(id int) {
|
||
idx := id % 16
|
||
mu[idx].Lock()
|
||
defer mu[idx].Unlock()
|
||
// ...
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 6. 性能优化最佳实践
|
||
|
||
#### **1. 使用 pprof 分析瓶颈**
|
||
|
||
```bash
|
||
# CPU 分析
|
||
go tool pprof -http=:8080 cpu.prof
|
||
|
||
# 内存分析
|
||
go tool pprof -http=:8080 heap.prof
|
||
|
||
# 火焰图
|
||
go tool pprof -http=:8080 -http=:8080 -pdf cpu.prof > cpu.pdf
|
||
```
|
||
|
||
---
|
||
|
||
#### **2. 优化热点代码**
|
||
|
||
```go
|
||
// 使用 pprof 找到热点函数
|
||
// go tool pprof -list functionName cpu.prof
|
||
|
||
// 优化前
|
||
func slow() {
|
||
for i := 0; i < 1000000; i++ {
|
||
s := fmt.Sprintf("%d", i) // 慢
|
||
_ = s
|
||
}
|
||
}
|
||
|
||
// 优化后
|
||
func fast() {
|
||
var b strings.Builder
|
||
for i := 0; i < 1000000; i++ {
|
||
b.WriteString(strconv.Itoa(i))
|
||
}
|
||
_ = b.String()
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 7. 阿里 P7 加分项
|
||
|
||
**深度理解**:
|
||
- 理解 pprof 的数据采集原理
|
||
- 理解 Go 的性能瓶颈(内存、CPU、Goroutine)
|
||
- 理解 Go 的 GC 对性能的影响
|
||
|
||
**实战经验**:
|
||
- 有使用 pprof 优化程序性能的经验
|
||
- 有优化并发程序的经验(减少锁、使用 Worker Pool)
|
||
- 有优化内存使用的经验(sync.Pool、预分配)
|
||
|
||
**性能优化**:
|
||
- 理解如何进行性能分析和瓶颈定位
|
||
- 理解如何优化 CPU 密集型代码
|
||
- 理解如何优化 I/O 密集型代码
|