-3

While reading https://golang.org/src/container/heap/example_pq_test.go I found that at line 27 they are using slice of pointers.

// A PriorityQueue implements heap. Interface and holds Items.
type PriorityQueue []*Item

But as per https://philpearl.github.io/post/bad_go_slice_of_pointers/, the slice of pointers benchmarks result is not good. I am just confused, when to use the slice of pointers and when not to use?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Parth Wadhwa
  • 577
  • 1
  • 7
  • 11
  • 5
    This might sound sarcastic, but you use a slice of pointers when you want to handle multiple values that individually are useful as pointers. So the question boils down to when to use pointers and when not to. For that see [Pointers vs. values in parameters and return values](https://stackoverflow.com/questions/23542989/pointers-vs-values-in-parameters-and-return-values). – icza Nov 26 '20 at 16:26
  • 4
    Who cares about microbenchmarks? Everything that is naturally handled as a pointer (e.g. because methods are available only on the pointer receivers) and needs to be stored in a slice is stored as a slice of pointers. This is non-problem: For almost all code it doesn't matter the the slightest; so why spend brain cycles? – Volker Nov 26 '20 at 16:36
  • 1
    imho, it is only to improve the api because the non pointer version seems much harder to use https://play.golang.org/p/3-kerktHbKe In that example it is simple, but in real case if you dont know the index of the item of which you are modifying the priority, then you have to scan the slice to find the Item and get its index before calling heap.Fix. –  Nov 26 '20 at 18:42

1 Answers1

1

Value types are copied while pointers are just references. A slice of value types could result in a lot of memory copying.

Imagine you'd have a slice of type [][64]byte. If you get one of the items via e.g. item := s[0] then it would copy 64 bytes while if the type were []*[64]byte then item := s[0] would just copy the size of a pointer. Total memory usage could also vary a lot if all the values of the items are stored multiple times in memory.

The benchmark you linked to benchmarks a struct with two integers which isn't all too different from a pointer in terms of size. It also allocates a new item on each iteration while the value type version allocates all the memory in one chunk once. It could look very different if the items were allocated beforehand.

It's really about value vs pointer in general not just for slices.