LoginSignup
22
10

More than 5 years have passed since last update.

io.Readerから[]byteへの変換のベンチマーク

Last updated at Posted at 2017-01-18

TL;DR

io.Readerから[]byteに変換する際はio.Copyを使おう.

buf := new(bytes.Buffer)
io.Copy(buf, reader)
ret := buf.Bytes()

 io.Readerは値を一度読むと二回目以降はデータが無くなるようで,ベンチマークのコードが正しくなかったので修正しました.

背景

httpの通信結果を取得した際など,res.Bodyから値を読み取ると思う.
res.Bodyio.ReadCloserインターフェースを実装しているので,io.Readerから何らかの方法で取得する.

その時に幾つか方法がありそうだったので,どれがパフォーマンスが良いのか調べてみた.

方法

調べた範囲で見つけられたのは,ioutil.ReadAllbytes.BufferReadFromメソッド,io.Copyメソッドの3つだった.

それぞれのベンチマークを示す.

const N int = 1000

func BenchmarkReadAll(b *testing.B) {
    data := make([]byte, N)

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        reader := bytes.NewBuffer(data)
        ioutil.ReadAll(reader)
    }
}

func BenchmarkReadFrom(b *testing.B) {
    data := make([]byte, N)

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        reader := bytes.NewBuffer(data)
        buf := new(bytes.Buffer)
        buf.ReadFrom(reader)
        buf.Bytes()
    }
}

func BenchmarkReadCopy(b *testing.B) {
    data := make([]byte, N)

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        reader := bytes.NewBuffer(data)
        buf := new(bytes.Buffer)
        io.Copy(buf, reader)
        buf.Bytes()
    }
}

ベンチマークの実行コマンドを以下に示す.

go test -benchmem -bench .

結果

ベンチマーク結果を示す.

BenchmarkReadAll-4       2000000           944 ns/op        2160 B/op          3 allocs/op
BenchmarkReadFrom-4      1000000          1049 ns/op        2160 B/op          3 allocs/op
BenchmarkReadCopy-4      2000000           598 ns/op        1248 B/op          3 allocs/op
PASS
ok      _/Users/taisuke/manga   5.770s

ReadAllReadFromがほぼ同じ性能で,io.Copyが倍以上の性能となっていることがわかる.

まとめ

ReadAllReadFromがほぼ同じ性能だったので,ソースを見てみると,ReadAllの内部でReadFromが呼ばれていた.
bytes.Bufferから[]bytestringも取得できるので,ささっと書きたい時以外ioutil.ReadAllは使わなくてもいいかもしれない.

初心者なので,これじゃ正しく動かなかったり,他にもっとこんな方法があるよとか,ベンチマークの方法がおかしいとかあったら,指摘してください.泣いて喜びます.

22
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
10