Go Slice 里面放 Struct,應(yīng)該使用指針嗎?
很多人寫go 也寫了好多年了,但還是對go 的內(nèi)存結(jié)構(gòu)一無所知,除了內(nèi)存對齊以外,比如slice 里面到底應(yīng)該放結(jié)構(gòu)體([]MyStruct)還是結(jié)構(gòu)體指針([]*MyStruct),還是一頭霧水。
Go slice 里面放struct 應(yīng)該使用指針嗎?
我們先通過一個性能測試,看一下這兩種情況下的性能對比:
我們先定義一個結(jié)構(gòu)體:
- type MyStruct struct {
- A int
- B int
- }
然后通過go自帶的benchmark測試一下,首先是使用指針的場景:
- func BenchmarkSlicePointers(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- slice := make([]*MyStruct, 0, 100)
- for j := 0; j < 100; j++ {
- slice = append(slice, &MyStruct{A: j, B: j + 1})
- }
- }
- }
然后是直接放結(jié)構(gòu)體的場景:
- func BenchmarkSliceNoPointers(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- slice := make([]MyStruct, 0, 100)
- for j := 0; j < 100; j++ {
- slice = append(slice, MyStruct{A: j, B: j + 1})
- }
- }
- }
跑一下:
- name time/op
- SlicePointers-8 2.50µs ± 2%
- SliceNoPointers-8 117ns ± 1%
- name alloc/op
- SlicePointers-8 1.60kB ± 0%
- SliceNoPointers-8 0.00B
- name allocs/op
- SlicePointers-8 100 ± 0%
- SliceNoPointers-8 0.00
可以看到使用指針的時候的性能要明顯低于直接使用結(jié)構(gòu)體,原因也很明顯,因為使用指針的時候,切面里面放的是指針,指針在單獨指向一個內(nèi)存區(qū)域,而直接使用結(jié)構(gòu)體則可以節(jié)省這部分的開銷。
所以,只有我們需要修改原來數(shù)據(jù),必須指針傳遞的時候,我們才將指針放到slice里面,這點希望大家注意。