2015-11-30 1 views
7

私は、次の機能を持っていますGolangはすでにコピーオンライトとしてこれらを渡すことでこれを処理していますか?Golang関数のパラメータはコピーオンライトとして渡されますか? <code>excludedPatterns</code>が変わることはありませんから、私は(関数にするたびにそれを渡していない)varがグローバルすることによって、それを最適化する必要があり、</p> <pre><code>func checkFiles(path string, excludedPatterns []string) { // ... } </code></pre> <p>私は思ったんだけど、かん:

編集:スライスをポインタとして渡すことができると思いますが、コピーオンライトの動作(存在する場合)と、一般的に値渡しについて心配する必要があるかどうかは疑問ですポインタによって。

+0

http://blog.golang.org/go-slices-usage-and-internals –

+0

することができますまた、これを読んでくださいhttp://stackoverflow.com/questions/1863460/whats-the-point-of-having-pointers-in-go – kingSlayer

+4

1. Goには書き込み時にコピーがありません。 2.すべてが常にGoのコピーによってパスされます。 3.一部のタイプ(スライスやマップなど)には非表示のポインタが含まれているため、参照渡しされる可能性がありますが、そうではありません。 4. excludePatternを渡すのがコード内のパフォーマンスのボトルネックになっている場合は、ビールをお支払いします。 5.スライスをポインタで渡すことは、関数内から変更しない限り、完全に無意味です(スライスのサイズが小さい場合)。 – Volker

答えて

7

関数の名前から判断すると、パラメータをグローバル変数に移動するだけでパラメータを渡すために必要な時間とスペースを節約することもできます(IOファイルのチェックなど)関数を呼び出して値を渡すよりも)。

Goのスライスは、バッキングアレイへのポインタを持つ構造体のようなもので、長さと容量が2つの小さなものです。バッキング配列がどれほど大きくても、パススライスは常に効率的です。もちろん、スライスヘッダを変更しない限り、ポインタを渡すことは考慮しないでください。

Goのパラメータは常に値によって渡され、渡される値のコピーが作成されます。ポインタを渡すと、ポインタ値がコピーされて渡されます。スライスが渡されると、スライス値(小さな記述子)がコピーされて渡されます。これは同じバッキング配列(コピーされません)を指します。

また、関数内でスライスに複数回アクセスする必要がある場合は、コンパイラがさらに最適化/キャッシングを行うことができるため、通常はパラメータが余分なゲインになります。グローバル変数の場合は注意が必要です。 Go Slices: usage and internals

そして、あなたは、パフォーマンス上の正確な数値が必要な場合は、ベンチマーク:スライスとその内部に関する

もっと!

ここでは、2つのソリューション(引数としてスライスを渡すかグローバルスライスにアクセスする)の間に違いがないことを示す少しベンチマークコードがあります。 slices_test.goなどのファイルにそれを保存して、go test -bench .

package main 

import (
    "testing" 
) 

var gslice = make([]string, 1000) 

func global(s string) { 
    for i := 0; i < 100; i++ { // Cycle to access slice may times 
     _ = s 
     _ = gslice // Access global-slice 
    } 
} 

func param(s string, ss []string) { 
    for i := 0; i < 100; i++ { // Cycle to access slice may times 
     _ = s 
     _ = ss // Access parameter-slice 
    } 
} 

func BenchmarkParameter(b *testing.B) { 
    for i := 0; i < b.N; i++ { 
     param("hi", gslice) 
    } 
} 

func BenchmarkGlobal(b *testing.B) { 
    for i := 0; i < b.N; i++ { 
     global("hi") 
    } 
} 

出力例でそれを実行します。

testing: warning: no tests to run 
PASS 
BenchmarkParameter-2 30000000    55.4 ns/op 
BenchmarkGlobal-2  30000000    55.1 ns/op 
ok  _/V_/workspace/IczaGo/src/play 3.569s 
関連する問題

 関連する問題