Closed4

ストリームについて

ShionShion

メモリとストリーム

プログラムがデータを扱う方法は以下の2種類。

  • メモリ
  • ストリーム

メモリ

メモリの形態でデータを扱うというのは、必要な情報が一か所に全て集まっていると捉えまとめてそのまま扱う形式のこと。

ストリーム

ストリームの形態でデータを扱うというのは、必要な情報は少しずつソースから流れてくるものと捉えて扱う形式のこと。例えば以下のような操作がストリーム形式で扱われる。

  • キーボード入力
  • ファイル操作
  • ネットワーク通信

参考

https://yosuke-furukawa.hatenablog.com/entry/2014/12/01/155303
https://christina04.hatenablog.com/entry/2017/01/06/190000

ShionShion

ストリームについてもっと詳しく

ストリームとは?

ストリームとは、データを一連の流れとして順番に扱う概念。
データをバケツリレーのように1つずつ順番に渡して処理していくイメージ。
全体を一度に扱うのではなく、少しずつ流れていくるデータをリアルタイムに処理する

具体例を出すと、YouTubeで動画を見るときは最初にすべての映像データをDLするのではなく再生中に少しずつ映像データが送られてくる。これがストリームで、順次流れてきてそれをすぐに表示していく流れになる。

プログラミングにおけるストリーム

  • ファイルの読み込み
    1GBのファイルを一度に読み込むとメモリを大量消費してしまう。
    ストリームを使うと少しずつデータを読み込んで、その都度処理できるためメモリの節約になる。
  • ネットワーク通信
    データを送受信する際も、一度にまとめてではなく、順次データが届いて処理される。これもストリームの概念。

ストリームの利点

  • メモリ節約
    すべてのデータを一度に読み込まず、少しずつ処理するためメモリ節約できる。
  • リアルタイム処理
    データが届いたらすぐに処理できるため、リアルタイムで動作するシステムに適している(動画再生やチャットアプリなど)
ShionShion

Go のストリーム

Go では io.Readerio.Writer でストリームを実現できる。
よく知られているのが、HTTPリクエストをサーバー内でエンコード/デコードする際に、Marshal/Unmarshalでメモリに展開するのではなくストリームを使って処理をしよう、というやり方である。

http.HandleFunc("/hello", func(w http.ResponseWriter, req *http.Request) {
    // BAD
    var greeting Greeting

    data, _ := io.ReadAll(req.Body)
    err := json.Unmarshal(data, &greeting) // メモリ展開してしまっている

    // Good
    var greeting Greeting
    err := json.NewDecoder(req.Body).decode(&greeting)
})
このスクラップは25日前にクローズされました