🔥

シリアライズ(直列化)の説明がしっくりこないので調べた

2024/02/02に公開

検索で出てくるシリアライズの説明が難しい

シリアライズを検索すると、以下のような説明が出てくるが、正直にいうとあまりしっくりきておらず、シリアライズという言葉の使用を避けていた。クラスのインスタンスなどをファイルに出力したり、ネットワークを通じて送信することだ、という雰囲気は感じ取れたので、これまでは「インスタンスをファイルに出力して」などと表現して、シリアライズという言葉は使わずにお茶を濁してきた。

様々な要素を組み合わせた複合的なデータや、コンピュータで実行中のプログラムがメインメモリ上に展開しているオブジェクトなどを、一定のデータ形式や変換規則に従って文字列やバイト列に変換し、保存したり送受信できるようにすることを指す。
https://e-words.jp/w/シリアライズ.html

しかし、そろそろちゃんとシリアライズの意味を理解して、適切な文脈で使えるようになりたい、と思ったので調べてみた。

シリアライズとは

最初に、シリアライズの意味について書く。紛らわしいことに、シリアライズにはまったく異なる2つの意味がある。

  • データのシリアライズ(直列化):
    • オブジェクトを一連のビットに変換すること
  • スレッドやプロセスのシリアライズ(逐次化):
    • マルチスレッドやマルチプロセスの環境で、複数の主体が同じリソースに同時にアクセスすることを制御すること

今回書くのは、データのシリアライズの話である。区別するために、タイトルに「(直列化)」と書いた。

日本語では意味ごとに異なる訳語を用意しているのは素晴らしいと思う。しかし、現実のコミュニケーションで「直列化」や「逐次化」を聞いたことがないのは残念ではある(シリアライズは聞くことがある)。

なぜシリアライズ(直列化)と呼ぶのか

「ビット化」や「バイナリ化」ではダメなのか、と最初に思った。シリアルという言葉に馴染みがないし、直列の対義語は並列だと理解しているが、普段プログラムで扱っているオブジェクトがそもそも並列だと意識したことがないから、直列にするといわれても何がどう変わるのかイメージできない。

プログラム実行中にメモリに存在するオブジェクトは、メモリ上の異なる場所に散らばっていたり、複雑な構造をしていることが多いらしい。シリアライズは、これらのデータを一列に並んだビット(0または1の情報)に変換する。「ビット列に変換」ということもあるし、「バイナリデータに変換」と表現されることもあるが、バイナリデータはビットの列で構成されるデータのことなので、どちらも同じ意味である。

シリアルという言葉の意味

シリアルという単語には、連続的や一連という意味があるらしい。そういわれると、分散していたデータを連続したビットに変換する処理をシリアライズと呼ぶことは適切な気がしてくる。よく考えたら、オブジェクトは最初からビットであるわけなので、「ビット化」では不適切だろう。

「オブジェクトを一連のビットに変換すること」という説明において大事なのは「一連の」の部分だったのだ、と思い知った。

シリーズとシリアルは別物

シリアライズの説明を探していて、「オブジェクトに関するデータを、シリーズのように連続したビット列に変換するプロセス」という文章に出会った。なるほど、シリアルというのはシリーズのことなのか、と納得したのだけれど、シリアルとシリーズは別の意味らしい。

どちらも「連続するもの」のような意味なので紛らわしいが、「トイストーリー2」「トイストーリー3」のように、それぞれで完結している作品はシリーズと呼び、複数回にわたってひとつのストーリーが展開されるものはシリアルと呼ばれる。シリアルの複数形がシリーズというわけではない。

pythonのデータ構造に「Series」というものがあり、これは他のプログラミング言語でいう配列のようなものだ。これを想像すると、たしかにシリーズの要素はそれぞれが完結した意味を持っている。一方、シリアライズは個々のビットには意味がなく、全体で一つの意味になるので、シリーズではなくシリアルだな、と納得した。

シリアライズをすることの利点

一般的には、どんな場合にシリアライズを使うのか気になったので調べた。

  • データの永続化:
    • オブジェクトの状態をファイルに保存する
    • ゲームのセーブデータの保存などに利用
  • ネットワークで送信:
    • オブジェクトを別のコンピュータに送信する
    • バイナリやテキストの形式に変換する必要がある
  • キャッシング:
    • 頻繁にアクセスされるオブジェクトを一時的に保存する
  • JSONやXML形式への変換:
    • オブジェクトは内部的にシリアライズされてからテキスト形式に変換される

データの永続化や転送などの用途は想像していたが、JSON形式に変換するときにも内部的にシリアライズが実行されていることは盲点だった。そう考えると、キャッシュの場合もJSONなどのテキスト形式より、バイナリ形式で保存したほうが効率が良いのは当然だ。JSON形式の場合、読み込んだ後にフォーマットをパース(解析)するオーバーヘッドもかかる。

ちなみにオブジェクトとは

シリアライズの説明で、必ず「オブジェクト」という表現が使われていたので、「インスタンス」だとニュアンスが違うのか、と疑問に思った。そこでオブジェクトとインスタンスの違いについても確認した。

オブジェクトという用語はインスタンスよりも一般的で、整数や文字といったプリミティブなデータ型から、より複雑な構造体やクラスのインスタンスまで含むらしい。最近のプログラミング言語では、整数や配列といった基本的なデータ型も特定のクラスのインスタンスとして扱われるので、いまひとつしっくりこない。

納得できなかったのでもう少し調べてみたところ、オブジェクト指向におけるオブジェクトの定義は、これとは異なることがわかった。オブジェクト指向では、属性とメソッドを持つものをオブジェクトというらしい。さらに、クラスに基づいて生成される具体的なインスタンスのこともオブジェクトと呼んだりする。非常に紛らわしい。

Discussion