2017-09-21 5 views
5

Iは、コードのいくつかの性能に敏感なセクションの割り当てを低減するために、バッファ・プールを使用するプログラムを有します。このようなスライスをその容量まで拡張する最も簡単な方法は何ですか?

何か:play link

// some file or any data source 
var r io.Reader = bytes.NewReader([]byte{1,2,3}) 

// initialize slice to max expected capacity 
dat := make([]byte, 20) 

// read some data into it. Trim to length. 
n, err := r.Read(dat) 
handle(err) 
dat = dat[:n] 

// now I want to reuse it: 
for len(dat) < cap(dat) { 
     dat = append(dat, 0) 
} 

log.Println(len(dat)) 
// add it to free list for reuse later 
// bufferPool.Put(dat) 

私はいつも必要な最大サイズよりも大きいことが保証された固定長のスライスを、割り当てます。私は、バッファを使用する実際のデータの長さにサイズを小さくする必要があるが、私はまた、その中に、私はそれを必要とする次の時間を読み取るために再び最大サイズである必要があります。それは私が使用しているものですので、

スライスを拡大するための私の知っている唯一の方法は、appendです。しかし、ループは非常に汚い感じ。そして潜在的に非効率的である。私のベンチマークはそれが恐ろしいことではないことを示していますが、よりよい方法が必要であると感じています。

私はスライスの内部表現についてのビットのみを知っているが、私は何とか実際にデータを追加することなく、長さの値をオーバーライドすることができれば、それは本当のいいだろう。私はそれをゼロにする必要は全くありません。

これを実行するより良い方法はありますか?その容量にスライスを「拡張」

答えて

7

は単にslice expressionあり、かつ高い指標として、容量を指定します。高い指数は長さよりも短くする必要はありません。制限がある:配列や文字列の

0 <= low <= high <= len(a)場合、指数は、そうでなければ、それらが範囲外にある、範囲内にあります。スライスについて、上限インデックスは、スライス容量cap(a)なく長さです。

例:

b := make([]byte, 10, 20) 
fmt.Println(len(b), cap(b), b) 

b = b[:cap(b)] 
fmt.Println(len(b), cap(b), b) 

出力(Go Playground上でそれを試してみてください):あなたはスライスしてその容量にスライスを拡張することができます

10 20 [0 0 0 0 0 0 0 0 0 0] 
20 20 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 
+0

うわー、私は今、馬鹿だと感じる。私はそれを試して、範囲や何かを得たことを誓う。しかし、あなたがその能力の下にとどまっている限り、それは確かに機能します。 – captncraig

関連する問題