2016-07-13 4 views
0

私がしようとしているのは、io.MultiWriterがstdoutとバイトバッファに書き込むことです。このようなもの:bytes.Bufferは多くの再アロケーションを実行しますか?

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()) 
} 

私はこれを行うことで私は自分自身を撮影しているのですか?これは、配列に挿入されるたびに配列を再割り当てしますか?もしそうなら、おそらくもっと良い方法がありますか?私は時期尚早に最適化していますか?

+0

snarkyになろうとはしませんが、いつでも[source](https://golang.org/src/bytes/buffer.go?s=402:854#L7)を読むことができます。 – squiguy

+1

あなたが正しいですし、Goのソースコードは実際には*非常に*可読です:) –

答えて

1

これは、バイトバッファに書き込む標準的な方法です。

bytes.Bufferタイプは、スライスと同様に成長します。したがって、内部的にバイトスライスであるバッファは、そこに入るデータが現在のバイトスライスの容量を超えるたびに倍になります。次に、古いスライスからのデータがこの新しいスライスにコピーされ、その後に新しいデータが追加されます。

平均でこのアルゴリズムは一定の時間(償却)で実行されるため、大きなパフォーマンス上のペナルティはありません。

+1

Re:「線形に実行する」...線形複雑さはO(n)です。容量を倍増するバッファ拡張方法は、償却された一定の時間複雑度またはO(1)を生成する。通常、挿入操作はO(1)で実行され、時折O(n)のコストがかかります。償却原価はO(1)になります。 –

+0

右に修正しました。 – abhink

+0

また、展開方法は、現在の容量の2倍の実際の容量です。** **必要な拡張のサイズ(挿入される文字列の長さ)。 500バイトを空のバッファに挿入すると、500バイトが割り当てられます。現在100000バイトを持つバッファに500バイトを挿入すると、200500バイトが割り当てられます。長時間実行されているOPのようなロギングアプリケーションでは、バッファが空になっていないとパニックに陥る可能性があります。 –

関連する問題