代码

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

所以:一般情况下,对于需要修改原对象值,或占用内存比较大的结构体,选择传指针。对于只读的占用内存较小的结构体,直接传值能够获得更好的性能。