代码
package main
import (
"fmt"
"time"
)
type TM1 struct {
array [1024 * 64]byte
}
type TM2 struct {
array [1024*64 + 1]byte
}
func TestTM1() {
// 仅生成结构体
startTime := time.Now()
for i := 0; i < 10000; i++ {
s := TM1{}
s.array[0] = 1
}
fmt.Println("等于64KB结构体:", time.Since(startTime))
// 生成结构体指针
startTime = time.Now()
for i := 0; i < 10000; i++ {
s := new(TM1)
s.array[0] = 1
}
fmt.Println("等于64KB结构体指针:", time.Since(startTime))
}
func TestTM2() {
startTime := time.Now()
for i := 0; i < 10000; i++ {
s := TM2{}
s.array[0] = 1
}
fmt.Println("大于64KB结构体:", time.Since(startTime))
startTime = time.Now()
for i := 0; i < 10000; i++ {
s := new(TM2)
s.array[0] = 1
}
fmt.Println("大于64KB结构体指针:", time.Since(startTime))
}
func main() {
TestTM1()
TestTM2()
}
结果
结论
堆栈分配的效率差距很大,在64位机器上64KB 是一个节点。
TM1 单结构体大小=64KB,无论是结构体还是结构体指针都在栈中生成。
TM2 单结构体大小>64KB,结构体在栈中生成,结构体指针在堆中生成。
但是
fmt.Println(s)fmt.Println(&s)go build -gcflags '-m -l' 文件escapes to heapmoved to heapinterface{}
所以:一般情况下,对于需要修改原对象值,或占用内存比较大的结构体,选择传指针。对于只读的占用内存较小的结构体,直接传值能够获得更好的性能。