Files
bulma/escape/optimize_demo.go
T

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)
}