Why should I use a pointer ( performance)?

huangapple go评论71阅读模式
英文:

Why should I use a pointer ( performance)?

问题

我想知道在原始对象和指向对象的指针之间是否有任何性能基准测试。

  • 我知道在引用类型(例如映射)上使用指针是没有意义的,所以请不要提到它。
  • 我知道如果数据需要更新,你“必须”使用指针,所以请不要提到它。

我找到的大多数答案/文档基本上都是重新表述官方文档中的指导方针:
... 如果接收器很大,比如一个大的结构体,使用指针接收器会更便宜。

我的问题很简单,什么是“大”?对于字符串来说,指针是否过度?对于具有两个字符串的结构体呢?对于具有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).

答案1

得分: 3

在使用指针不合适的情况下,可以考虑引用类型(切片、映射和通道)。

正如在这个帖子中提到的:

引用的概念只是指用于引用某个东西的东西。它并不神奇。

指针是一个简单的引用,告诉你要去哪里查找。
切片告诉你从哪里开始查找以及查找多远。
映射和通道也只是告诉你要去哪里查找,但它们所引用的数据以及对其支持的操作更加复杂。

关键是所有实际数据都是间接存储的,你所持有的只是访问它的信息。
因此,在许多情况下,除非出于某种原因需要双重间接引用,否则不需要添加另一层间接引用。

正如twotwotwo在“参数和返回值中的指针与值”中详细说明的那样,字符串、接口值和函数值也是使用指针实现的。
因此,你很少需要在这些对象上使用指针。

英文:

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.

答案2

得分: 1

引用官方的golang文档中的内容:

> ...考虑到效率。如果接收器很大,比如一个大的结构体,使用指针接收器会更加便宜。

英文:

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.

答案3

得分: -1

由于可能存在不同的性能目标,很难给出确切的条件。作为一个经验法则,默认情况下,所有大于128位的对象应该通过指针传递。以下是该规则的可能例外情况:

  • 如果你正在编写对延迟敏感的服务器,希望最小化垃圾回收压力。为了实现这一目标,你的Request结构体应该有一个byte[8]字段,而不是指向包含byte[8]的Data结构体的指针。这样只需要进行一次内存分配,而不是两次。

  • 如果你正在编写的算法在传递结构体并进行复制时更易读。

等等。

英文:

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.

huangapple
  • 本文由 发表于 2015年3月20日 05:18:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/29155202.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定