📏

Zero-copy deserializationとは【ChatGPTとの共著】

2022/12/06に公開

Wasmerの記事を読んでいる中で、Zero-copy deserializationという知らない単語が出てきたので勉強しました。

シリアライズとデシリアライズ

そもそも、シリアライズとデシリアライズとは何なのかを復習します。

シリアライズとは

プログラムが持つデータを通信や保存のしやすいような形式に変換することです。
通信や保存のしやすいような形式とは、例えば文字列データのことを指します。
Pythonを例に考えてみると、リストや辞書がネストしたデータをJSON形式の文字列データに変換するなどです。

デシリアライズ

シリアライズが分かれば、デシリアライズはその逆と理解すれば問題ないです。
JSON形式のデータがただの文字列のままだとプログラムでは扱いにくいので、プログラムで扱いやすい形に戻すことを指します。

サンプルプログラム

ここで、ChatGPTにデシリアライズのサンプルプログラムをPythonで作ってもらいました。
======== Chat GPT ========
Pythonでデシリアライズを行う場合、標準ライブラリの「pickle」モジュールを使用することができます。以下に、配列のデータをシリアライズして文字列として保存し、その文字列をデシリアライズして配列のデータに戻すプログラムの例を示します。

import pickle

# 配列のデータ
data = [1, 2, 3, 4, 5]

# 配列のデータを文字列にシリアライズする
data_string = pickle.dumps(data)

# シリアライズされた文字列を配列のデータにデシリアライズする
data_array = pickle.loads(data_string)

# 結果を出力
print(data_array)

上記プログラムを実行すると、配列のデータが文字列に変換され、その文字列が元の配列のデータに戻されます。
==========================
pickleというモジュールの存在を知りませんでしたが、Pythonの公式ドキュメントを調べてみるとちゃんとありました。使用用途も正しいです。(すごい)
https://docs.python.org/ja/3/library/pickle.html

ただし、今回はより親しみ深いJSONモジュールを使った例を参考にします。

import json

# JSON文字列
json_data = '{"key1": "value1", "key2": "value2"}'

# JSON文字列をデシリアライズする
data = json.loads(json_data)

# 辞書データを表示する
print(data)

Zero-copy deserialization

その名の通り、「コピーを行わない」デシリアライズの方法のことです。
通常のデシリアライズでは、シリアライズ化されているデータをメモリ上に展開する必要があるため、デシリアライズに時間がかかります。
一方で、Zero-copy deserializationは、データを展開せずにそのまま利用することができるため高速なデシリアライズが可能になります。

PythonでZero-copy deserializationをする方法

ChatGPTに対して、Pythonを使ってZero-copy deserializationができるかを尋ねたところ、次のような回答がえられました。
======== Chat GPT ========
Pythonでは、標準ライブラリの「pickle」モジュールを使用して、デシリアライズを行うことができます。しかし、「pickle」モジュールを使用してデシリアライズを行う場合は、通信されたデータを展開しなければなりません。つまり、「pickle」モジュールを使用して行われるデシリアライズは、Zero-copy deserializationに該当しません。

PythonでZero-copy deserializationを行う場合は、特殊なライブラリを利用する必要があります。例えば、「ujson」や「rapidjson」といったライブラリが提供するデシリアライズ機能を使用することで、Zero-copy deserializationを行うことができます。ただし、これらのライブラリは、標準ライブラリには含まれていないため、別途インストールする必要があります。
==========================

ChatGPTが言及している「ujson」や「rapidjson」について、どちらも実在する高速なモジュールです。
「ujson」についてはゼロコピーを使っている根拠を見つけることができませんでしたが、「rapidjson」については、該当する記述を見つけることができました。
rapidjsonのドキュメントのFeatures > Parsingの部分です。

Faster than convention parsing: no allocation for strings, no copy (if string does not contain escapes), cache-friendly.
https://rapidjson.org/md_doc_features.html

速度の比較

rapidjsonの方が早いですね。

1000件のデータでrapidのデシリアライズの方が速い (10.704%)
json: 0.001秒、rapidjson: 0.001秒
10000件のデータでrapidのデシリアライズの方が速い (13.814%)
json: 0.005秒、rapidjson: 0.004秒
100000件のデータでrapidのデシリアライズの方が速い (9.030%)
json: 0.040秒、rapidjson: 0.036秒
1000000件のデータでrapidのデシリアライズの方が速い (28.166%)
json: 0.573秒、rapidjson: 0.447秒

コードはChat GPTに一緒に作りました。

ベンチマークのコード
import rapidjson
import time
import json

# データ数を指定する
data_nums = [1000, 10000, 100000, 1000000]

# 各データ数で比較する
for num in data_nums:
    data = {}

    # データ数分のデータを作成する
    for i in range(1, num+1):
        data["data{}".format(i)] = {"key1": "value1", "key2": "value2"}

    # JSON文字列を作成する
    json_data = json.dumps(data)

    # pickleでデシリアライズ
    start = time.time()
    json.loads(json_data)
    end = time.time()
    json_time = end - start

    # rapidjsonでデシリアライズ
    start = time.time()
    rapidjson.loads(json_data)
    end = time.time()
    rapidjson_time = end - start

    # デシリアライズ時間を比較
    if json_time < rapidjson_time:
        diff = (rapidjson_time - json_time) / json_time * 100
        print("{}件のデータでjsonのデシリアライズの方が速い ({:.3f}%)".format(num, diff))
        print("json: {:.3f}秒、rapidjson: {:.3f}秒".format(json_time, rapidjson_time))
    else:
        diff = (json_time - rapidjson_time) / rapidjson_time * 100
        print("{}件のデータでrapidのデシリアライズの方が速い ({:.3f}%)".format(num, diff))
        print("json: {:.3f}秒、rapidjson: {:.3f}秒".format(json_time, rapidjson_time))

感想

Zero-copy deserializationについて記事を書く目的で、軽い気持ちでChatGPTも触ってみたら想像以上に役に立って驚きました。
ChatGPTはもちろん完璧ではないので鵜呑みは禁物ですが、人と会話しながら記事を書いている気分になり非常に捗りました。また、会話のコンテキストが非常に大事で、いきなり質問をするのではなく会話の流れの中で質問をすることで良い回答が得られるように感じました。(これは人との会話でも同様ですね)
そこまで深い内容でなければChatGPTが簡単に答えてくれるので、技術記事などを書いている者としては、AIに聞けば分かるような内容の記事ではなく、中身のある記事を書けるように頑張りたいです。

ChatGPTとの会話の一例

次のような質問をいきなりすると
「ゼロコピー・デシリアライゼーションとは何ですか?」
======== Chat GPT ========
ゼロコピー・デシリアライゼーションは、データを破壊しないように複製する方法です。これにより、データを元の場所から移動させることができます。この技術は、データを安全かつ効率的に管理するために使用されます。
==========================
このように少し的からずれた回答が返ってきますが。
「デシリアライズとは何ですか?」
と聞いた後に、ゼロコピー・デシリアライゼーションについて聞くと、
======== Chat GPT ========
ゼロコピー・デシリアライゼーションとは、データをデシリアライズする際に、データをコピーすることなく直接読み込む方法を指します。通常、デシリアライズを行うときには、データを一旦メモリ上に読み込んでから処理するため、データ量が大きい場合は処理が遅くなる場合があります。一方、ゼロコピー・デシリアライゼーションを行うと、データを直接読み込むため、データをコピーする手間が省けることで処理が高速化されます。また、データをコピーすることなく扱うことで、メモリを効率よく活用することができます。
==========================
このように、私が先ほど書いたゼロコピー・デシリアライゼーションの説明よりしっかりと答えてくれます...

参考文献

https://rkyv.org/zero-copy-deserialization.html
https://brunocalza.me/what-zero-copy-serialization-means/

Discussion