ホームページ > バックエンド開発 > Golang > メモリを飽和させることなく、大量のデータ ストリームを JSON にエンコードするにはどうすればよいでしょうか?

メモリを飽和させることなく、大量のデータ ストリームを JSON にエンコードするにはどうすればよいでしょうか?

Patricia Arquette
リリース: 2024-10-27 17:24:31
オリジナル
819 人が閲覧しました

How can you encode large streams of data into JSON without memory saturation?

メモリ飽和を発生させずに大規模なデータ ストリームをエンコードする

JSON 形式へのエンコードが必要な大規模なデータセットを操作する場合、json パッケージのデフォルトの動作は非効率になる可能性があります。エンコード前にデータセット全体をメモリにロードする必要があるため、パフォーマンスの問題が発生する可能性があります。

この制限に対処するには、フィールド Foo とオブジェクトをストリーミングするチャネル Bar を持つ構造体があるシナリオを考えてみましょう。 Bar の内容全体をメモリに保持せずに、t を JSON にエンコードしたいと考えています。

バイト操作によるカスタム JSON エンコーディング

現在、json パッケージにはストリーミング エンコーディングがサポートされていません。回避策は、バイト ストリームに書き込むことによって JSON 文字列を手動で構築することです。これは次のように実行できます。

w := os.Stdout
w.WriteString(`{ "Foo": "` + t.Foo + `", "Bar": [`)

for x := range t.Bar {
    _ = json.NewEncoder(w).Encode(x)
    w.WriteString(`,`)
}

w.WriteString(`]}`)
ログイン後にコピー

JSON エンコーダ API を再考する

改善されたエンコーディング/json パッケージには、ストリーミング エンコーディングを可能にする改訂された Marshaler インターフェイスが含まれます。これは次のようになります。

type Marshaler interface {
    MarshalJSON(io.Writer) error
}
ログイン後にコピー

エンコーディング/json パッケージへのパッチ適用 (オプション)

エンコーディング/json パッケージが要件を満たしていない場合は、パッチの適用を検討できます。ストリーミング チャネルを処理するために考えられる変更は次のとおりです:

case reflect.Chan:
    e.WriteByte('[')
    i := 0
    for {
        x, ok := v.Recv()
        if !ok {
            break
        }
        if i > 0 {
            e.WriteByte(',')
        }
        e.reflectValue(x)
        i++
    }
    e.WriteByte(']')
ログイン後にコピー

標準ライブラリへのパッチ適用は注意して行う必要があり、互換性の問題が発生する可能性があることに注意してください。

以上がメモリを飽和させることなく、大量のデータ ストリームを JSON にエンコードするにはどうすればよいでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート