很多人寫go 也寫了好多年了,但還是對go 的內存結構一無所知,除了內存對齊以外,比如slice 里面到底應該放結構體([]MyStruct)還是結構體指針([]*MyStruct),還是一頭霧水。
Go slice 里面放struct 應該使用指針嗎?
我們先通過一個性能測試,看一下這兩種情況下的性能對比:
我們先定義一個結構體:
- 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})
- }
- }
- }
然后是直接放結構體的場景:
- 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
可以看到使用指針的時候的性能要明顯低于直接使用結構體,原因也很明顯,因為使用指針的時候,切面里面放的是指針,指針在單獨指向一個內存區域,而直接使用結構體則可以節省這部分的開銷。
所以,只有我們需要修改原來數據,必須指針傳遞的時候,我們才將指針放到slice里面,這點希望大家注意。
原文鏈接:https://www.toutiao.com/i7048616935805829671/