- 2010年07月21日 (水)
- Tweet
ActionScriptでのデータ保存形式の比較(XML・JSON・ByteArray)
ActionScriptでデータを外部に保存するときの方法について考察してみます。その前に質問ですが、次のデータオブジェクトをテキストファイルに保存する場合に、どのフォーマットがベストでしょうか。
var data:Object = { family: [ {name : "自分", age : 10}, {name : "父", age : 30} ], pet: [ {name : "ポチ", age : 5}, {name : "ユズピ", age : 3} ], };
ご察知の方が多いと思いますがJSONやXMLで保存するのが簡単そうです。しかし次の場合はどうでしょうか。
var data:MyHouse = new MyHouse( [ new Person("自分", 10), new Person("父", 30) ], [ new Animal("ポチ", 5), new Animal("ユズピ", 3) ], );
MyHouseとPerson、Animalというのはここではカスタムクラスとして用意したものとします。カスタムクラスが使われていた場合に、その型情報も保存するかどうかが悩ましいところです。
つまり、このようなケースも含めて最適な保存方法はどの形式なのか、XML・JSON・ByteArrayの3つを比較して紹介します。
XML
最も知名度が高く、テキストエディタでの編集が容易なことから最もFlashで扱われるデータ形式の一つです。ActionScript3.0ではE4Xによる解析も可能なので利用しやすいのが特徴です。
メリット
- 柔軟なデータ保持が可能。
- テキストデータなので再編集が容易(ヒューマンリーダブル)。
- E4Xによる解析が容易。
- 汎用データ形式なので別環境での再利用が可能。
デメリット
- ASネイティブデータの保存にはXMLへの自前パーサーを用意する必要がある。
- データ容量が大きくなる。
- 解析ロジックによっては計算時間がかかる。
Flashではビルドインでネイティブ←→XMLの変換機能が提供されていないため、その機能を自分で作る必要があります。そのため「自前パーサー」という言葉を使いました。
冒頭の質問のデータ形式については、自前パーサーの設計次第でカスタムクラスの変換・復元が可能です。Adobeが提供しているas3corelibのようなデファクトスタンダードなライブラリがない分、JSON形式と比べて採用しにくいのが難点かもしれません。
参考までに冒頭のデータをXMLに変換した場合の一例を示します。
<node type="myproject.data::MyHouse"> <node type="Array"> <node type="myproject.data::Person"> <name type="String">自分</name> <age type="Number">10</age> </node> <node type="myproject.data::Person"> <name type="String">父</name> <age type="Number">30</age> </node> </node> <node type="Array"> <node type="myproject.data::Animal"> <name type="String">ポチ</name> <age type="Number">5</age> </node> <node type="myproject.data::Animal"> <name type="String">ユズピ</name> <age type="Number">3</age> </node> </node> </node>
JSON
XMLよりもネイティブに近い形で保存できるため、データの変換・復元の扱いが容易な形式です。ActionScript 3.0では、Adobeが提供しているas3corelibのJSONクラスを使用することで、JSON形式への変換・再現が可能です。以下は、as3corelibのJSONクラスについての機能を評価したものとなります。
メリット
- as3corelibなどデファクトスタンダードなライブラリが存在する。
- テキストデータなので再編集が容易。
- ECMA標準のObject/Array形式で保存するため汎用性がある。
- JavaScriptなど別言語での再利用も可能。
デメリット
- 型指定が保存できない。
- データ容量が大きくなる(ただしXMLよりコンパクト)。
- デコード/エンコードの計算時間がかかる。
冒頭の質問のデータ形式については、カスタムクラスであってもpublicな変数や、読み取り可能なアクセサであればJSONデータとして変換可能です。ただし、JSONデータは型情報が保存されないため、ネイティブ(Object, Array, Number, Boolean, String)の型しか利用できず、型情報まで含めた復元はできません。
参考までに冒頭のデータをJSONに変換した場合の一例を示します。ご覧の通り型指定はありませんが、ネイティブのデータ形式と比べて非常に近い形で変換されているのがわかります。
[ [ {"age":10,"name":"自分"}, {"age":30,"name":"父"} ], [ {"age":5,"name":"ポチ"}, {"age":3,"name":"ユズピ"} ] ]
ちなみに、JSONの使い方やXMLとの比較については、当ブログで紹介して紹介していますので、そちらも参考ください。
ByteArray
保存形式としてはあまり認知されていないと思いますが、ByteArrayにはwriteObject/readObjectというメソッドがあります。これはActionScriptのネイティブなデータ情報をバイナリとして扱うことができるため、データの再現性に優れた形式です。テキスト情報ではなくバイナリのため、データの変換・復元の計算も非常に高速なため、用途が限定されるのであればもっともパフォーマンスが高い形式かもしれません。
メリット
- ネイティブのデータで保持するため、完全な復元が可能。
- クラスの型指定も保持可能。
- バイナリなのでデータ容量がコンパクト。
- データのデコード/エンコードの計算時間が早い。
デメリット
- ActionScript 3.0以外での再利用が困難。
- テキストエディタなどでの再編集が困難。
- ByteArrayに対する知識が必要。
サーバーサイドへ保存する場合などバイナリでは扱いが複雑になるため、場合によってはBase64変換を使ってバイナリを文字列に変換してみるのもいいかもしれません(Base64は元のバイナリデータに対して138%のデータ容量になります)。wonderflにて検証したところでは、ByteArray+Base64変換と、JSON変換だと前者のほうが圧倒的に早い結果を得ました。データ容量についても前者のほうが圧倒的にコンパクトで有利です。
検証結果
- [ Performance – Write ] ByteArray.writeObject vs JSON.encode
- [ Performance – Read ] ByteArray.readObject vs JSON.decode
参考までに冒頭のデータをByteArray + Base64に変換した場合の一例を示します。とてもヒューマンリーダブルなデータとは言えませんが、その分文字数も少なくデータ容量がコンパクトなことがわかります。
CQUBCjMrbXlwcm9qZWN0LmRhdGEuUGVyc29uCXByZWYHYWdlCW5hbWUKIydteXByb2plY3QuZGF0 YS5QcmVmBWlkBgQNBgtUT0tZTwQbBglZQVNVCgEKBQQbBgtPU0FLQQQdBglOT0JV
まとめ
一概にどれがベストであるかは評価が難しいところですが、評価のポイントとして次を検討してみるといいかもしれません。
- 変換・復元の計算速度
- 変換後のデータ容量
- 型指定まで含めた復元が必要かどうか
- 別アプリで保存データを編集するかどうか(汎用性)
- 保存形式が利用可能かどうか(文字列かバイナリか)
- 保守・永続性
それでは次回は、私が開発したJSONクラスに取って代わるXMLで型指定データも保持可能なライブラリについて紹介したいと思います。
2010年07月22日(木) 09:35
[…] ActionScriptでのデータ保存形式の比較(XML・JSON・ByteArray) | ClockMaker Blog (tags: as3) […]