はじめに
今回はSystem.Text.Json
を利用して直接UTF-8バイト配列にシリアライズ & UTF-8バイト配列からデシリアライズする方法を紹介したいと思います。
また公式ドキュメントには文字列ベースのメソッド(UTF-16)を使用するよりもUTF-8バイト配列のシリアル化は約5から10%高速だと表記されています。
UTF-8 バイト配列へのシリアル化は、文字列ベースのメソッドを使用するより約 5 から 10% 高速です。 違いは、バイト (UTF-8) を文字列 (UTF-16) に変換する必要がないことから生じます。
概要
System.Text.Json
はMicrosoftが提供するハイパフォーマンスなJsonシリアライザーです。
Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data.
// DeepL翻訳
オブジェクトをJavaScript Object Notation (JSON)テキストにシリアライズし、JSONテキストをオブジェクトにデシリアライズする、高性能で割り当ての少ない型を提供します。また、UTF-8 でエンコードされた JSON テキストを読み書きする型や、データの構造化されたビュー内で JSON 要素のランダムアクセスを行うための、読み取り専用のインメモリドキュメントオブジェクトモデル (DOM) を作成する型も提供します。
使い方
基本的な使い方を書いていきます。
public class Person { public int Age { get; set; } public string Name { get; set; } } public static void Main() { var target = new Person { Age = 40, Name = "John", }; // UTF-8のバイト配列にシリアライズ // NOTE: stringはUTF-16なので注意 // SerializeToUtf8Bytesメソッド or Serializeメソッドの引数にUtf8JsonWriter でUTF-8バイト配列にシリアル化 byte[] data = JsonSerializer.SerializeToUtf8Bytes(target); // 007b,0022,0041,0067,0065,0022,003a,0034,0030,002c,0022,004e,0061,006d,0065,0022,003a,0022,004a,006f,0068,006e,0022,007d // 中身的には「 {"Age":40,"Name":"John"} 」 Console.WriteLine(string.Join(",", data.Select(x => x.ToString("x4")))); // デシリアライズ // ReadOnlySpan<byte> or Utf8JsonReader を引数に受け取るとUTF-8から逆シリアル化する var person = JsonSerializer.Deserialize<Person>(data.AsSpan()); Console.WriteLine(person.Age); // 40 Console.WriteLine(person.Name); // John }
シリアライズ
コメントにも書きましたが、以下の2種類の方法でシリアライズします。
JsonSerializer.SerializeToUtf8Bytes
JsonSerializer.Serialize
の引数にUtf8JsonWriter
を渡す
// JsonSerializer.SerializeToUtf8Bytes byte[] data = JsonSerializer.SerializeToUtf8Bytes(json); // JsonSerializer.Serialize + Utf8JsonWriter using MemoryStream stream = new MemoryStream(); using Utf8JsonWriter writer = new Utf8JsonWriter(stream); // ... byte[] data = JsonSerializer.SerializeToUtf8Bytes(writer);
デシリアライズ
以下の2種類があります。
JsonSerializer.Deserialize
の引数にReadOnlySpan<byte>
を渡すJsonSerializer.Deserialize
の引数にUtf8JsonReader
を渡す
// ReadOnlySpan<byte> ReadOnlySpan<byte> data = "{\"Age\":40,\"Name\":\"John\"}"u8; Preson person = JsonSerializer.Deserialize<Person>(data); // Utf8JsonReader ReadOnlySpan<byte> data = "{\"Age\":40,\"Name\":\"John\"}"u8; Utf8JsonReader reader = new Utf8JsonReader(data); var person = JsonSerializer.Deserialize<Person>(ref reader);