86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
type Person struct {
|
|
Name string
|
|
Age int
|
|
}
|
|
|
|
// 优化1:避免不必要的指针传递(小结构体)
|
|
// 优化前:指针传递,可能触发逃逸
|
|
func processPersonOld(p *Person) string {
|
|
return fmt.Sprintf("%s is %d years old", p.Name, p.Age)
|
|
}
|
|
|
|
// 优化后:值传递,不逃逸
|
|
func processPersonNew(p Person) string {
|
|
return fmt.Sprintf("%s is %d years old", p.Name, p.Age)
|
|
}
|
|
|
|
// 优化2:提前确定切片容量,避免动态扩容逃逸
|
|
// 优化前:动态扩容,底层数组逃逸
|
|
func sliceEscape() []int {
|
|
s := make([]int, 0)
|
|
for i := 0; i < 100; i++ {
|
|
s = append(s, i)
|
|
}
|
|
return s
|
|
}
|
|
|
|
// 优化后:指定容量,不逃逸
|
|
func sliceNoEscape() []int {
|
|
s := make([]int, 0, 100) // 编译期确定容量
|
|
for i := 0; i < 100; i++ {
|
|
s = append(s, i)
|
|
}
|
|
return s
|
|
}
|
|
|
|
// 优化3:使用对象池复用对象,减少堆分配
|
|
var personPool = sync.Pool{
|
|
New: func() interface{} {
|
|
return &Person{} // 初始化对象,仅分配一次(或按需分配)
|
|
},
|
|
}
|
|
|
|
// 优化前:频繁创建对象,多次堆分配
|
|
func createPersonOld(name string, age int) *Person {
|
|
return &Person{Name: name, Age: age} // 每次调用都逃逸,触发堆分配
|
|
}
|
|
|
|
// 优化后:复用对象池中的对象,减少堆分配
|
|
func createPersonNew(name string, age int) *Person {
|
|
p := personPool.Get().(*Person)
|
|
p.Name = name
|
|
p.Age = age
|
|
return p
|
|
}
|
|
|
|
// 释放对象到池
|
|
func releasePerson(p *Person) {
|
|
// 重置对象状态(避免残留数据)
|
|
p.Name = ""
|
|
p.Age = 0
|
|
personPool.Put(p)
|
|
}
|
|
|
|
func main() {
|
|
// 优化1测试
|
|
p := Person{Name: "Alice", Age: 25}
|
|
fmt.Println("优化1-值传递:", processPersonNew(p))
|
|
|
|
// 优化2测试
|
|
s1 := sliceEscape()
|
|
s2 := sliceNoEscape()
|
|
fmt.Printf("优化2-切片:逃逸len=%d, 不逃逸len=%d\n", len(s1), len(s2))
|
|
|
|
// 优化3测试
|
|
p1 := createPersonNew("Bob", 30)
|
|
fmt.Println("优化3-对象池:", *p1)
|
|
releasePerson(p1)
|
|
}
|