3

I'm wondering if there is any perf benchmark on raw objects vs pointers to objects.

  • I'm aware that it doesn't make sense to use pointers on reference types (e.g. maps) so please don't mention it.
  • I'm aware that you "must" use pointers if the data needs to be updated so please don't mention it.

Most of the answers/ docs that I've found basically rephrase the guidelines from the official documentation: ... If the receiver is large, a big struct for instance, it will be much cheaper to use a pointer receiver.

My question is simply what means "large" / "big"? Is a pointer on a string overkill ? what about a struct with two strings, what about a struct 3 string fields??

I think we deal with this use case quite often so it's a fair question to ask. Some advise to don't mind the performance issue but maybe some people want to use the right notation whenever they have to chance even if the performance gain is not signifiant. After all a pointer is not that expensive (i.e. one additional keystroke).

The user with no hat
  • 10,166
  • 20
  • 57
  • 80
  • 5
    I wrote a lot about when to use/not use pointers [over here](http://stackoverflow.com/questions/23542989/pointers-vs-values-in-parameters-and-return-values/23551970#23551970). Don't sweat the perf until you know you're working on code that's your bottleneck; to know when it'll help or hurt, you really might have to experiment on your actual code, to take account of cache effects and such. – twotwotwo Mar 19 '15 at 21:39
  • The question is really only about the performance issue not the other uses cases. – The user with no hat Mar 20 '15 at 20:49
  • I've also updated the question to clarify that it's not about when to use pointers. – The user with no hat Mar 20 '15 at 21:02
  • Rules of thumb: In the other answer, I noted the stdlib has a function that pushes 10 words of data on the stack, so maybe you can see that as the upper bound past which you'd tend to use a pointer. I definitely wouldn't use a pointer to two strings (four words). Around three strings (six words) I'd start measuring, if the performance really mattered. It usually doesn't really matter. – twotwotwo Mar 20 '15 at 22:34
  • And rules of thumb, or even careful analysis, won't always predict what performs best--if it's crucial you just have to benchmark your app. Pointer versus value has a lot of different effects (on amount of copying, memory locality, GC time, number of allocations, etc.), so you may have to measure to see how they balance out in your case. – twotwotwo Mar 20 '15 at 22:38

3 Answers3

3

An example where it doesn't make sense to use a pointer is for reference types (slices, maps, and channels)

As mentioned in this thread:

The concept of a reference just means something that serves the purpose of referring you to something. It's not magical.

A pointer is a simple reference that tells you where to look.
A slice tells you where to start looking and how far.
Maps and channels also just tell you where to look, but the data they reference and the operations they support on it are more complex.

The point is that all the actually data is stored indirectly and all you're holding is information on how to access it.
As a result, in many cases you don't need to add another layer of indirection, unless you want a double indirection for some reason.

As twotwotwo details in "Pointers vs. values in parameters and return values", strings, interface values, and function values are also implemented with pointers.
As a consequence, you would rarely need a to use a pointer on those objects.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 4
    Strings, interface values, and function values are also implemented with pointers. There's a lot about it [over here](http://stackoverflow.com/questions/23542989/pointers-vs-values-in-parameters-and-return-values/23551970#23551970). – twotwotwo Mar 19 '15 at 21:42
  • Should I understand from this answer that for anything that's not a reference type I should use a pointer? i.e. a string. – The user with no hat Mar 20 '15 at 20:53
  • @Theuserwithnohat that for anything that's not a reference type, you *can* use a pointer. That doesn't mean that you *have* to, but it can make sense mainly when passing around large structures. – VonC Mar 20 '15 at 21:01
  • @Theuserwithnohat "maybe some people want to do the right thing whenever they have to chance even if the performance gain is not signifiant": that is called http://c2.com/cgi/wiki?PrematureOptimization and is well documented: don't worry too soon, that is why go comes with a benchmarking framework (http://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go) – VonC Mar 20 '15 at 21:07
  • @VonC I'm wondering if using different integer types is considered premature optimisation too. – The user with no hat Mar 20 '15 at 21:10
  • @Theuserwithnohat it is not, if you measure it (with benchmark tests), like some did for the go web frameworks (https://quip.com/Ha0bAfeh1ZVY) – VonC Mar 20 '15 at 21:11
  • 1
    This doesn't go anywhere... I will benchmark the pointer vs non-pointer thing when I get time and post the results as my answer. I think using the pointer improperly is same as using the wrong integer type or even worse. The question is about correctness of the pointer usage and all the answers basically provide the same rhetoric. "Use pointers when you think the receiver is big/large" though "large" or "big" is not something that you can measure unless you have a comparison value. – The user with no hat Mar 20 '15 at 21:36
1

To quote the official golang documentation

...the consideration of efficiency. If the receiver is large, a big struct for instance, it will be much cheaper to use a pointer receiver.

Raed
  • 519
  • 1
  • 6
  • 23
-1

It's very hard to give you exact conditions since there can be different performance goals. As a rule of thumb, by default, all objects larger than 128 bits should be passed by pointer. Possible exceptions of the rule:

  • you are writing latency sensitive server, so you want to minimise garbage collection pressure. In order to achieve that your Request struct has byte[8] field instead of pointer to Data struct which holds byte[8]. One allocation instead of two.

    • algorithm you are writing is more readable when you pass the struct and make a copy

etc.

Lukasz Madon
  • 14,664
  • 14
  • 64
  • 108