Open6

Goのvalueとpointerについて

kurokuro

いつポインタを使うべきか

A common idea is that when you use pointers your application will be faster, because you’ll avoid copying data around all the time. When Java came around, one of the complaints was that Java was slow because you’d be doing a pass-by-value all the time. Hence perhaps it’s no surprise that in Go we find the same idea persisting.

Yet, Passing pointers in Go is often slower than passing values. This is a result of Go being a garbage collected language. When you pass a pointer to a function, Go needs to perform Escape Analysis to figure out if the variable should be stored on the heap or the stack. This already adds a bit of overhead, but in addition the variable could be stored on the heap. When you store a variable on the heap, you also lose time when the GC is running.

なるほど、ポインタか値のどちらが速いかは、ヒープかスタックに入るのかで決まるのか。。。
https://medium.com/@meeusdylan/when-to-use-pointers-in-go-44c15fe04eac

kurokuro

If you just pass everything by value, you always run on the stack and don’t have to incur the overhead of garbage collection. (The GC will still run by default. But having less on the heap will make the GC have less work to do).

基本的にはvalueはスタックに入るってことかな

kurokuro

So are pointers never more performant than passing the values? Actually, that would be a false statement as well. Pointers can have a benefit when you have structs containing lots of data. When you have these, the overhead of the garbage collector might be negated by the overhead you’d get when copying large amounts of data.

ただ大きなデータを持つ構造体はポインタを使った方がいいらしい
GCのオーバーヘッドは、大量のデータをコピーするときに発生するオーバーヘッドよりも少ないことがあるから。

kurokuro

If you’re using values, you’ll always get the default-zero value. In some cases, you might want to really know if something is absent or just filled out. For example, if you have a struct representing exams with scores that a student took, if a struct is empty and has a score of 0, does this mean the student did a really bad job or does this mean the student was absent?

By using a pointer, the default-zero value is a nil pointer, which could be used to signify the absence of a value. There’s other ways of doing this, you could create a struct such as:

type exam struct {
    score   int
    present bool
}

デフォルトがnillなのか0なのかっていうのを表現できるという違いもあるのか。

kurokuro

やっぱり同じようなこと書いてある

Variable must not be modified
We do not have other option, but pass variable by value. So that variable cannot be modified downstream. And vice versa, if variable is expected to be modified, it must be passed by pointer.

Variable is a large struct
If variable is a large struct and performance is an issue, it’s preferable to pass variable by pointer. So that to avoid expensive copying of the whole struct in memory.

Variable is a map or slice
Maps and slices are reference types in Go and should be passed by values.

不変の値の時はvalueが良くて、巨大な構造体の時はpointerの方が良くて、mapとsliceの時は、valueの方良いらしい。

https://codewithyury.com/golang-pass-by-pointer-vs-pass-by-value/

kurokuro

Passing by value often is cheaper
Even though Go looks a bit like C, its compiler works differently. And C analogy does not always work with Go. Passing by value in Go may be significantly cheaper than passing by pointer. This happens because Go uses escape analysis to determine if variable can be safely allocated on function’s stack frame, which could be much cheaper then allocating variable on the heap. Passing by value simplifies escape analysis in Go and gives variable a better chance to be allocated on the stack.

値の方が、スタックにアロケートしてくれやすいから、良い場合が多いって感じかな