2016-07-13 5 views
0

Was ich versuche zu tun ist eine io.MultiWriter, die in einen Stdout und in einen Byte-Puffer schreibt. Etwas wie folgt aus:Führt bytes.Buffer viele Reallocs durch?

package main 

import "bytes" 
import "fmt" 
import "io" 
import "os" 

func main() { 
    var b bytes.Buffer 
    multi := io.MultiWriter(&b, os.Stdout) 
    fmt.Fprintf(multi, "each of these strings\n") 
    fmt.Fprintf(multi, "might be large\n") 
    fmt.Fprintf(multi, "and there are many of them\n") 
    fmt.Println(b.String()) 
} 

Was ich frage mich, wenn ich mich in den Fuß drehe durch dies zu tun? Wird das Array für jede Einfügung neu zugewiesen? und wenn ja, gibt es vielleicht einen besseren Weg? Werde ich vorzeitig optimiert?

+0

Nicht versuchen, snarky zu sein, aber Sie können immer auch die [Quelle] (https://golang.org/src/bytes/buffer.go?s=402:854#L7) lesen. – squiguy

+1

Sie haben Recht, und Gos Quellcode ist tatsächlich * sehr * lesbar :) –

Antwort

1

Dies wäre die Standardmethode zum Schreiben in einen Bytepuffer.

bytes.Buffer Typ wächst ähnlich wie Slices. Ein Puffer, der intern ein Byte-Slice ist, verdoppelt sich also jedes Mal, wenn die Daten, die in ihn hineingehen, die Kapazität des aktuellen Byte-Slices überschreiten. Dann werden die Daten aus dem alten Slice in dieses neue Slice kopiert, wonach neue Daten angehängt werden.

Dieser Algorithmus wird im Durchschnitt in konstanter Zeit (amortisiert) ausgeführt, so dass es keine wesentlichen Leistungseinbußen gibt.

+1

Re: "führt linear aus" ... Lineare Komplexität ist O (n). Die Puffererweiterungsmethode der Verdopplung der Kapazität erzeugt eine amortisierte konstante Zeitkomplexität oder O (1). Nominell läuft eine Einfügeoperation in O (1) mit gelegentlichen Erweiterungen, die O (n) kosten. Die fortgeführten Anschaffungskosten werden zu O (1). –

+0

richtig .. machte die Korrektur. – abhink

+0

Beachten Sie außerdem, dass die Erweiterungsmethode doppelt so groß ist wie die aktuelle Kapazität _ ** plus ** _ die Größe des gewünschten Wachstums (Länge der einzufügenden Zeichenfolge). Das Einfügen von 500 Bytes in einen leeren Puffer weist 500 Bytes zu. Das Einfügen von 500 Bytes in einen Puffer, der aktuell über 100000 Bytes verfügt, weist 200500 Bytes zu. Für eine lange Laufzeit, Logging-Anwendung wie das OP vorschlägt, könnte dies zu einer Panik führen, wenn der Puffer nicht geleert wird. –