Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Why should we use bufio.ReadBytes, ReadString instead of ReadSlice in most cases?

Why should we use bufio.ReadBytes, ReadString instead of ReadSlice in most cases?

#fukuokago の Lightning Talk資料です。

Google Slide is here https://docs.google.com/presentation/d/1Q_HpKo0zqYSMTietQrQatOEjVutkIyyLUDzQNRukJFg/edit?usp=sharing .

Kazuki Higashiguchi

July 14, 2020
Tweet

More Decks by Kazuki Higashiguchi

Other Decks in Technology

Transcript

  1. Why should we use bufio.ReadBytes, ReadString instead of ReadSlice in

    most cases? fukuoka.go, JULY 14 2020 #ちょっと深堀り #コードリーディング #社内でGophersCodeReadingPartyはじめました #fukuokago Presented by @hgsgtk
  2. { About me GitHub/Twitter: @hgsgtk BASE BANK, Inc. (BASE, Inc.)

    東京からお邪魔してます #fukuokago
  3. “Because the data returned from ReadSlice will be overwritten by

    the next I/O operation, most clients should use ReadBytes or ReadString instead.” godoc.org bufio package func (*Reader) ReadSlice https://godoc.org/bufio#Reader.ReadSlice
  4. “ReadLine is a low-level line-reading primitive. Most callers should use

    ReadBytes('\n') or ReadString('\n') instead or use a Scanner.” godoc.org bufio package func (*Reader) ReadLine https://golang.org/pkg/bufio/#Reader.ReadLine
  5. ReadSlice の仕様 戻り値が上書きされる例 #1 https://play.golang.org/p/Drl1FjauMeM (Copyright: 同僚の @budougumi0617 さんの再現コード) ←

    1. buffer から読み取る ← 2. 内部の buffer が上書きされるような操作をする ← 3. 再度 “1.” で取得した値を表示 4. ReadSlice の場合は、元のbufferのsliceの ため、 bufferの上書きにより、中身が変わっている
  6. ReadSlice の仕様 戻り値が上書きされる例 #2 https://play.golang.org/p/BRhnRMsFa59 ← 1. buffer から読み取る ←

    2. 内部の buffer が上書きされるような操作をする ← 3. 再度 “1.” で取得した値を表示 4. ReadSlice の場合は、元のbufferのsliceの ため、 bufferの上書きにより、中身が変わっている
  7. “ReadSlice reads until the first occurrence of delim in the

    input, returning a slice pointing at the bytes in the buffer.” godoc.org bufio package func (*Reader) ReadSlice https://godoc.org/bufio#Reader.ReadSlice → 戻り値は、bufferのsliceなので後続のbufferへの操作で中身が変わる
  8. ReadBytes, ReadString, ReadSlice, ReadLine の関係性 Reader.ReadString(delim byte) (string, error) Reader.ReadBytes(delim

    byte) ([]byte, error) Reader.ReadSlice(delim byte) ([]byte, error) call call → を使用すべきなのはなぜ? Reader.ReadLine() ([]byte, bool, error) call
  9. ReadString -> ReadBytes https://golang.org/src/bufio/bufio.go?s=11350:11404#L474 func (b *Reader) ReadString(delim byte) (string,

    error) { bytes, err := b.ReadBytes(delim) return string(bytes), err } ReadString は ReadBytes の戻り値 []byte を string 型に変換するだけ
  10. slice の 配列ポインタを比較してみる https://play.golang.org/p/Vom_IJf8Ua7 ← 1. もともとの[]byte の .pointer ←

    2. ReadSlice / ReadBytes で取得し た []byte の .pointer ↓ 3. ReadSlice は同じアドレス ReadBytes の場合は違うアドレスと なってる
  11. “in most cases” に当てはまらないときって? • メモリ使用量が気になるケースで、 の 使用に利点がありそう • For

    many applications, a single line is sufficient: hence, some commenters suggested ReadLine() or something similar.
  12. まとめ #ちょっと深堀り • の戻り値は、 の なので後 続の への操作で中身が変わる • では、コピーしているため、元のバッファに対する

    オペの影響を受けない • メモリ効率が気になる場合だと、 を用 いるという判断もありそう