2017-09-21 15 views
5

我有一個程序使用緩衝池來減少代碼中幾個性能敏感部分的分配。什麼是最簡單的方法來擴大其「容量」切片?

像這樣: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

4

您可以展開切片及其容量切片:

s = s[:cap(s)] 
相關問題