2017-09-21 5 views
5

Ich habe ein Programm, das einen Pufferpool verwendet, um Zuordnungen in einigen leistungsempfindlichen Abschnitten des Codes zu reduzieren.Was ist der einfachste Weg, um ein Segment zu seiner Kapazität zu erweitern?

Etwas wie folgt aus: 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) 

ich immer fester Länge Scheiben zurechnen, die erforderlich ist garantiert größer als die maximale Größe. Ich muss die Größe auf die tatsächliche Datenlänge reduzieren, um den Puffer zu verwenden, aber ich brauche es auch, um wieder die maximale Größe zu haben, um es das nächste Mal einzulesen, wenn ich es brauche.

Die einzige Möglichkeit, ein Stück zu erweitern, ist mit append, also das ist, was ich benutze. Die Schleife fühlt sich allerdings sehr schmutzig an. Und möglicherweise ineffizient. Meine Benchmarks zeigen, dass es nicht schrecklich ist, aber ich habe das Gefühl, dass es einen besseren Weg geben muss.

Ich weiß nur ein bisschen über die interne Darstellung von Slices, aber wenn ich den Längenwert nur irgendwie außer Kraft setzen könnte, ohne tatsächlich Daten hinzuzufügen, wäre es wirklich nett. Ich muss es nicht wirklich auf Null stellen oder so.

Gibt es einen besseren Weg, dies zu erreichen?

Antwort

7

"Erweitern" eines Slice auf seine Kapazität ist einfach ein slice expression, und die Kapazität als den hohen Index angeben. Der hohe Index muss nicht kleiner als die Länge sein. Die Einschränkung ist:

Für Arrays oder Strings, die Indizes sind in Reichweite, wenn 0 <= low <= high <= len(a), da sie sich außerhalb des Bereichs liegen. Bei Schichten ist die obere Indexgrenze die Schichtkapazität cap(a) und nicht die Länge.

Beispiel:

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

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

Output (versuchen Sie es auf dem 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

Wow, Ich fühle mich jetzt albern. Ich schwöre, ich habe das probiert und bin aus dem Spiel. Aber es funktioniert tatsächlich, solange Sie unter der Kapazität bleiben. – captncraig

4

Sie ein Stück seiner Kapazität mit Slicing erweitern:

s = s[:cap(s)] 
Verwandte Themen