SlideShare uma empresa Scribd logo
1 de 34
Baixar para ler offline
研究課題:Java におけるシリアライズとデータ圧縮




       新規開発局 プログラマ
          大平哲也




            1
1     はじめに
CGM サイトなど、データが無尽蔵に増える種類のサイトを運営する際は、増え続けるデータの扱
いが重要である。一つの対応として、データを永続化(直列化、シリアライズ)する際にデータのサ
イズを減らすことでデータ転送量やディスク容量の削減を行い、パフォーマンスを維持したりリソー
スを有効活用する方法が考えられるが、ただ圧縮をすれば良い訳ではなく、復元時の速度や、プ
ログラムからの扱いやすさも現実的な問題としては重要な事項になる。
まとめると、データのシリアライズ方式の検討は以下の観点における検討が大事になる。
・ データの省サイズ化
・ シリアライズ・デシリアライズの速度
・ プログラミング側からみた構造の柔軟性、扱いやすさ
そこで、Java におけるシリアライズ手法について調査した。
本論では、Java における各種シリアライズ手法を調査ならびに比較検証することにより、上記3点
をバランスよく満たす、システムに適用しやすいシリアライズ手法を見出すことを目的とする。

2     動機
    2.1 Java シリアライズの遅さ
Java は標準の言語機構においてオブジェクトインスタンスのシリアライズをサポートしている1という
優秀な言語ではあるが、非常に汎用的に作られているため単純なデータ永続化を果たしたい時に
は冗長すぎる仕様がネックになるケースがあり、シリアライズ・デシリアライズの遅さ、ならびにシリア
ライズデータの大きさが問題となる。(他手法との性能比較についての詳細は後述する)

たとえば、Java RMI などの RPC 処理の際、デフォルトでは Serializable インターフェースを継承
したクラスをシリアライズ・デシリアライズしてやりとりを行うことになるが、単純なデータ構造のデータ
を Java シリアライズそのまま用いて実装すると、他手法のシリアライズ形式を用いる際よりもパフォ
ーマンス的に問題が発生することが考えられ、高負荷、高トラフィックなシステムであればある程こ
のデメリットは大きくなる。

    2.2 優秀な他手法の存在
近年は、多言語に対応可能でかつ高速・高機能なシリアライズ・デシリアライズ機構が多く世の中
に知られるようになっている。具体的には Google の Protocol Buffers2 、Hadoop の Hadoop
Avro3、筑波大学の古橋貞之氏が製作した Message Pack4などである。
それぞれ手法ごとに機能的、性能的な特徴があるが、Java のシリアライズ機構との性能比較を実
際に行い、各手法のメリット・デメリットを把握したいと考えた。

3     本論の流れ
まず、各種シリアライズ手法を概観する。
今回は Java の標準 API(Serializable、Externalizable)、JSON 形式へのシリアライズツール
(JSONIC、FlexJson)、Protocol Buffers、Hadoop Avro、Message Pack を対象とした。
その上で、それぞれの手法におけるシリアライズ・デシリアライズのパフォーマンスを調査し、比較し
た。今回はシリアライズ速度、デシリアライズ速度、シリアライズ後のデータサイズ、ならびに実装の

1

    http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3
    %82%BA
    なお他言語では Ruby では Marshal クラス、Python では Pickling により言語機構によりシリアライズがサポー
    トされている。
2   http://code.google.com/intl/ja/apis/protocolbuffers/docs/overview.html
3   http://hadoop.apache.org/avro/
4   http://sourceforge.jp/projects/msgpack/




                                         2
しやすさを評価軸とした。また、データ圧縮アルゴリズムを用いた際のパフォーマンスとデータサイ
ズについても合わせて調査した。
そして最後に、調査結果を基に BtoC サイト、CGM サイトなどに適用しやすい組み合わせについ
てまとめる。

4      各種シリアライズ手法
    4.1     Java 標準 API:Serializable
Java にて、オブジェクトインスタンスのシリアライズが必要な場合は、シリアライズ該当クラスにて
java.io.Serializable1インターフェースを継承する。
これだけで、そのクラスはシリアライズ対応クラスとなる。
      import java.io.Serializable;
      public class SerializableObject implements Serializable {
        private String name; //シリアライズのとき保存される。
        static String staticField; //クラス変数は無視される。
        private transient int hashCode; //transient キーワードが付いたフィールドは無視
      される。

           //シリアライズしたいクラスの実装...

      }2

実際のデータシリアライズ・デシリアライズを行う処理は自分で実装する必要がある。これらの処理
は Java RMI を用いる場合は Java RMI 機構が自動的に対応する。
      import java.io.FileOutputStream;
      import java.io.OutputStream;
      import java.io.ObjectOutputStream;

      //...

      SerializableObject object = new SerializableObject();
      OutputStream outputStream = new FileOutputStream("serializableObject.obj");
      ObjectOutputStream                     objectOutputStream=                  new
      ObjectOutputStream(outputStream);
      objectOutputStream.writeObject(object);3

実際シリアライズされたデータは以下のようなものになる。以下はシリアライズデータをバイナリエデ
ィタで閲覧したものである。
なお仕様については SUN の公式ドキュメントが詳しい4。
      ac ed 00 05 73 72 00 0d 74 65 73 74 2e 54 65 73

1   http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/io/Serializable.html
2

    http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3
    %82%BA#Serializable より引用
3

    http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3
    %82%BA#.E3.83.90.E3.82.A4.E3.83.8A.E3.83.AA.E3.83.95.E3.82.A1.E3.82.A4.E3.83.AB.E3.81.AB.
    E3.82.B7.E3.83.AA.E3.82.A2.E3.83.A9.E3.82.A4.E3.82.BA より引用
4   http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/serialization/index.html




                                                      3
74 42 65 61 6e 20 e9 e2         62 c4 df 79 42 02 00 03
      4a 00 02 69 64 4c 00 04        74 69 6d 65 74 00 10 4c
      6a 61 76 61 2f 75 74 69        6c 2f 44 61 74 65 3b 4c
      00 05 76 61 6c 75 65 74        00 12 4c 6a 61 76 61 2f
      6c 61 6e 67 2f 53 74 72        69 6e 67 3b 78 70 00 00
      00 00 00 00 00 01 73 72         00 0e 6a 61 76 61 2e 75
      74 69 6c 2e 44 61 74 65        68 6a 81 01 4b 59 74 19
      03 00 00 78 70 77 08 00         00 01 27 74 e6 d2 3c 78
      74 00 04 74 65 73 74
      (....sr..test.Tes
        tBean ..b..yB...
        J..idL..timet..L
        java/util/Date;L
        ..valuet..Ljava/
        lang/String;xp..
        ......sr..java.u
        til.Datehj..KYt.
        ...xpw....'t..<x
        t..test)

先頭の「ac ed」はシリアライズ形式を示すマジックナンバー。「00 05」は Java のバージョン番号と
なる。以降オブジェクトの定義や変数の定義、変数の値などが埋め込まれている。
ヘッダ情報やオブジェクトの定義の情報が含まれているため、単純にデータのみを構造化してシリ
アライズする手法よりもデータサイズが冗長となる。

    4.2    Java 標準 API:Externalizable
Java には、シリアライズデータフォーマットを自分で定義することができる API、Externalizable1
が用意されている。これを用いると、必要最低限な情報だけシリアライズすることも可能であり、デー
タサイズやシリアライズ・デシリアライズ速度の向上を果たすことも可能である。
Externalizable にてシリアライズを行いたい場合は、該当クラスにて java.io.Externalizable イン
ターフェースを継承した上で、必要なメソッド(writeExternal、readExternal)を実装する必要が
ある。
      import java.io.Externalizable;
      import java.io.ObjectOutput;
      import java.io.ObjectInput;
      public class SerializableObject implements Externalizable {
        private String name; //writeExternal(ObjectOutput)で指定されているため保存さ
      れるフィールド。
        private int id; //無視される。
        private int hashCode; //writeExternal(ObjectOutput)で指定されているため保存さ
      れるフィールド。
        //Externalizable で定義されているメソッドをオーバーライド。
        //保存したいフィールドを指定する。
        @Override public void writeExternal(ObjectOutput out) {
           out.writeChars(this.name);


1   http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/io/Externalizable.html




                                                      4
out.writeInt(this.hashCode);
           }
           //復元したいフィールドを指定する。
           @Override public void readExternal(ObjectInput in) {
             this.name = in.readLine();
             this.hasoCode = in.readInt();
           }

           //シリアライズしたいクラスの実装

      }1

シリアライズ、デシリアライズを行う処理の実装方法は、Serializable を用いた時と同様である。

4.1 で用いたクラスと同じもの(厳密にはクラス名が異なる2)を Externalizable にてシリアライズした
ものが以下となる。
      ac ed 00 05 73 72 00 1b       74 65 73 74 2e 45 78 74
      65 72 6e 61 6c 69 7a 61       62 6c 65 54 65 73 74 42
      65 61 6e a3 be c9 30 53       4a 7a f8 0c 00 00 78 70
      77 08 00 00 00 00 00 00       00 01 74 00 04 74 65 73
      74 73 72 00 0e 6a 61 76       61 2e 75 74 69 6c 2e 44
      61 74 65 68 6a 81 01 4b       59 74 19 03 00 00 78 70
      77 08 00 00 01 27 74 e6       d3 af 78 78
      (....sr..test.Ext
        ernalizableTestB
        ean...0SJz....xp
        w.........t..tes
        tsr..java.util.D
        atehj..KYt....xp
        w....'t...xx)

先頭のヘッダ情報や、オブジェクトの定義については Serializable と同様に存在するが、それ以
降のデータの定義が最低限のもののみ出力されているため、Serializable に比べてデータサイズ
が小さくなっている。

    4.3  JSON 形式:JSONIC
構造化されたデータのテキストシリアライズ方式としては、近年は JSON3 形式が普及し、とくに
BtoC サイトなどでは一般化している。
理由としては簡潔で直感的なデータ構造記法や、RFC に定義されている4など仕様の堅牢化、ライ
ブラリの充実などが上げられる。

1

    http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3
    %82%BA#Externalizable より引用
2   4.1 では「test.TestBean(74 65 73 74 2e 54 65 73 74 42 65 61 6e)、4.2 では
                                                                      」
    「test.ExternalizableTestBean    (74 65 73 74 2e 45 78 74 65 72 6e 61 6c 69 7a 61 62 6c 65 54 65 73 74
    42 65 61 6e)  」を使用している。
3   http://ja.wikipedia.org/wiki/JavaScript_Object_Notation
4   http://www.rfc-editor.org/rfc/rfc4627.txt




                                                    5
テキストシリアライズ手法としては他に XML1や YAML2などが存在するが、XML はスキーマ定義
が厳格に行える一方スキーマレスでも十分な軽いデータを扱うには冗長すぎる点がある。YAML
については JSON と同様の軽さがあるが、JSON 程一般化していない。
そのため、ここでは JSON のみを対象とし、まずは JSON の Java 用シリアライズライブラリとして高
機能な JSONIC3について触れる。

JSONIC は Apache Lisence Version2.0 で提供されているオープンソースライブラリである。
シリアライズ・デシリアライズの記述が以下のように極めてシンプルに行えることが特徴である。
      import net.arnx.jsonic.JSON;

      // POJO を JSON に変換します
      String text = JSON.encode(new Hoge());

      // JSON を POJO に変換します
      Hoge hoge = JSON.decode(text, Hoge.class);4

出力形式は以下のような純粋な JSON 形式となり、クラス名などのメタ情報は含まれない。
それ故にデータ構造としては簡潔ではあるがデシリアライズ時には復元先のオブジェクトの明示的
な指定が必須になる。(シリアライズデータの情報のみから復元することはできない)
      {"id":1,"time":1268976636047,"value":"test"}

記述が簡便であることと高機能であることがメリットだが、データのシリアライズ等に Apache
Commons の BeanUtils5を多用しており、必ずしも処理は高速では無い。
また、出力内容が JSON 形式になることを前提としているため、文字列のみや数値のみのデータ
など、JSON 形式に成り得ないデータのシリアライズが出来ない仕様になっているので注意が必要
である。

    4.4    JSON 形式:FlexJson
FlexJson も JSONIC と同様 Apache Lisence Version 2.0 で公開されているオープンソースライ
ブラリである。JSONIC と比べるとシリアライズデータにメタ情報(クラス名)が含まれ若干冗長であ
ること、いくつかのバグが散見されるなどの問題もあるが、JSONIC に比べて高速にシリアライズが
行えるので紹介する。

シリアライズ・デシリアライズの記述は以下のようになる。
      T obj;
      String json = new JSONSerializer().serialize(obj);
      T deserialized = new JSONDeserializer<T>().deserialize(json);

クラスの一階層だけをシリアライズ(Shallow Serialize)/全てのデータをシリアライズ(Deep
Serialize)したり、特定の名前空間の変数を include/exclude することができるのが FlexJson の
特徴である。また実装上もリフレクションを出来るだけ用いない工夫が見られる。

シリアライズ後のデータは以下のようになる。

1   http://ja.wikipedia.org/wiki/Extensible_Markup_Language
2   http://ja.wikipedia.org/wiki/YAML
3   http://jsonic.sourceforge.jp/
4   http://jsonic.sourceforge.jp/ より引用
5   http://commons.apache.org/beanutils/




                                                 6
{"class":"test.TestBean","id":1,"time":1268976636560,"value":"test"}

    4.5    Protocol Buffers
Protocol Buffers は Google が BigTable などの社内のシステムに用いているとされる、データシリ
アライズフォーマットと、そのデータの RPC 通信を行うためのフレームワークである。2008 年の7月
に Apache Lisence Version 2.0 のオープンソースプロジェクトとして外部に公開された。

Protocol Buffers は IDL1と呼ばれる独自 DSL 言語を基に各種プログラム言語用のソースコード
を自動生成できることが特徴である。IDL 定義文は以下のようなものである。
      package serializable.protobuf;

      message TestBean{
             required int32 id = 1;
             required string value = 2;
             required int64 time = 3;
      }

上記を拡張子.proto として保存し、コード生成用のコマンドを実行すると各種言語向けのデータ操
作用プログラムファイルが自動生成される。
      protoc --java_out=. --cpp_out=. --python_out=. ProtobufTestBean.proto

上記は、proto ファイルを基に Java、C++、Python のソースコードを自動生成する際のコマンドで
ある。
生成されるソースコードは自動生成という事もあってか非常に冗長で、上記 proto ファイルの場合
Java で 422 行、C++でヘッダとソースを合わせて 652 行、Python で 67 行となった。

データのシリアライズ・デシリアライズ処理は自動生成コードで堅牢に行われるためか、シリアライズ
されるデータ形式は非常にシンプルで無駄が無いものになっている。
4.3、4.4 と同じデータ構造を持つクラスをシリアライズした結果が以下になる。
      08 01 12 04 74 65 73 74 18 f6 e2 b3 e1 06
      (....test......)

データは非常にシンプルで省サイズ化が可能であるが、生成コードにクセがあり、既存のシステム
に導入するためには Protocol Buffers 向けに実装を作り直すことが必要となる。

   4.6    Hadoop Avro
Hadoop Avro は、分散並列処理フレームワークとして著名な Hadoop プロジェクト2のサブプロジェ
クトとして、Hadoop 創始者の Doug. Cutting 氏によって 2009 年4月に立ち上げられた3新しいプ
ロジェクトである。
Hadoop における RPC 処理や、  サブプロジェクトである Hadoop Pig4、   Hive5などでのシリ
アライズ形式、RPC 形式を統一する、という目的で立ち上げられたようである。

1

    http://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3
    %83%BC%E3%82%B9%E8%A8%98%E8%BF%B0%E8%A8%80%E8%AA%9E
2   http://hadoop.apache.org/
3   http://markmail.org/message/7cgrwoc4er4mr3bp
4   http://hadoop.apache.org/pig/
5   http://hadoop.apache.org/hive/




                                               7
非常に多機能なことと、    ドキュメントが皆無であることから全体像は詳述できないが、ここ
ではデータのシリアライズ方式についてのみ述べる。
Avro では、JSON 形式で記述したスキーマ定義を基にデータのシリアライズ、デシリアラ
イズを行う。たとえば配列形式でシリアライズを行いたい場合は
  {"type": "array", "items": "string"}
のような形で定義する。
なおスキーマ定義は Java クラスから自動生成することも可能である。

以下はシリアライズ時の処理である。
  DataFileWriter<T> writer = null;
  Schema schema = null;
  if(schemastr != null){
       schema = Schema.parse(schemastr);
  }else if(clazz != null){
       ReflectData reflect = ReflectData.get();
       schema = reflect.getSchema(clazz);
  }
  try{
       writer = new DataFileWriter<T>(new ReflectDatumWriter<T>(schema));
       writer.create(schema, out);
       writer.append(obj);
       writer.sync();
  }finally{
       if(writer != null)
                 writer.close();
  }

上記ソースでは、JSON 定義がある時は「Schema.parse」メソッドによりスキーマを生成
し、ない時は「ReflectData」インスタンスを用いて対象クラスからスキーマを生成してい
る。

デシリアライズ時は以下のような処理になる。
  DataFileStream<T> stream = null;
  Schema schema = null;
  if(schemastr != null){
       schema = Schema.parse(schemastr);
  }else if(clazz != null){
       ReflectData reflect = ReflectData.get();
       schema = reflect.getSchema(clazz);
  }
  try{
       stream = new DataFileStream<T>(is, new ReflectDatumReader<T>(schema));

      return stream.next();
  }finally{
      if(stream != null)




                                        8
stream.close();
  }

上記では一つのクラスファイルを前提とした処理になっているが、   複数のクラスをまとめて
シリアライズ・デシリアライズできることが Avro の一つの特徴である。

シリアライズしたデータは以下のようになる。
JSON によるスキーマ定義情報もシリアライズデータの中に含まれるため、やや冗長にな
っている。ただし、シリアライズ・デシリアライズ速度は優秀である。
  4f 62 6a 01 02 16 61 76 72 6f 2e 73 63 68 65 6d
  61 ca 02 7b 22 74 79 70 65 22 3a 22 72 65 63 6f
  72 64 22 2c 22 6e 61 6d 65 22 3a 22 50 72 69 6d
  69 74 69 76 65 54 65 73 74 42 65 61 6e 22 2c 22
  6e 61 6d 65 73 70 61 63 65 22 3a 22 74 65 73 74
  22 2c 22 66 69 65 6c 64 73 22 3a 5b 7b 22 6e 61
  6d 65 22 3a 22 69 64 22 2c 22 74 79 70 65 22 3a
  22 6c 6f 6e 67 22 7d 2c 7b 22 6e 61 6d 65 22 3a
  22 76 61 6c 75 65 22 2c 22 74 79 70 65 22 3a 22
  73 74 72 69 6e 67 22 7d 2c 7b 22 6e 61 6d 65 22
  3a 22 74 69 6d 65 22 2c 22 74 79 70 65 22 3a 22
  6c 6f 6e 67 22 7d 5d 7d 00 0c 64 69 4e 57 ee 5f
  83 7d a0 a8 7f b7 bb 60 33 02 18 02 08 74 65 73
  74 f4 cf b6 ce ee 49 0c 64 69 4e 57 ee 5f 83 7d
  a0 a8 7f b7 bb 60 33
  (Obj...avro.schem
     a..{"type":"reco
     rd","name":"Prim
     itiveTestBean","
     namespace":"test
     ","fields":[{"na
     me":"id","type":
     "long"},{"name":
     "value","type":"
     string"},{"name"
     :"time","type":"
     long"}]}..diNW._
     .}.....`3....tes
     t.....I.diNW._.}
     .....`3)

枯れたプロジェクトとは言い難いためまだまだいくつかのバグが散見されるので、
                                    使用には
注意が必要である。

   4.7    Message Pack
Message Pack は古橋貞之氏が作成したシリアライズライブラリで、Apache Lisence Version 2.0
にて公開されている。
特徴としては「性能を重視したシリアライズ形式」と謳われている通り、シリアライズ・デシリアライズの




                                       9
速度が非常に優秀であることが挙げられる。また、Java を含む各種言語向けの操作用ライブラリが
提供されている。

シリアライズは以下のような形で実装する。
  Packer pack = new Packer(out);
  if(schema == null){
      pack.pack(obj);
  }else{
      pack.packWithSchema(obj, schema);
  }

スキーマ情報が存在しなくてもシリアライズ可能であるが、明示的にデータフォーマットを指定した
い場合は独自書式のスキーマ定義を用意する必要がある。
たとえば配列を扱う場合は、以下のようにスキーマを定義する。
  (array string)

デシリアライズは以下のような形で実装する。
  Unpacker unpk = null;
  if(bufferSize > 0){
      unpk = new Unpacker(is, bufferSize);
  }else{
      unpk = new Unpacker(is);
  }
  for(Object obj : unpk){
      if(schema == null){
               return (T)obj;
      }else{
               return (T)schema.convert(obj);
      }
  }
  return null;

上記ソースでは一つのクラス前提の処理になっているが、Message Pack も Hadoop Avro と同様
に複数のクラスをまとめてシリアライズ・デシリアライズする事が可能になっている。

シリアライズデータは以下のようになる。以下は ASCII 文字を値としてもつ配列をシリアライズ化し
たものである。JSON フォーマットのデータをバイナリ化したかのような、非常にシンプルな構成に
なっていることが分かる。
  dc 00 2f a1 30 a1 31 a1   32 a1 33 a1 34 a1 35 a1
  36 a1 37 a1 38 a1 39 a1    3a a1 3b a1 3c a1 3d a1
  3e a1 3f a1 40 a1 41 a1   42 a1 43 a1 44 a1 45 a1
  46 a1 47 a1 48 a1 49 a1    4a a1 4b a1 4c a1 4d a1
  4e a1 4f a1 50 a1 51 a1   52 a1 53 a1 54 a1 55 a1
  56 a1 57 a1 58 a1 59 a1    5a a1 5b a1 5c a1 5d a1
  5e
  (../.0.1.2.3.4.5.
    6.7.8.9.:.;.<.=.




                                           10
>.?.@.A.B.C.D.E.
      F.G.H.I.J.K.L.M.
      N.O.P.Q.R.S.T.U.
      V.W.X.Y.Z.[.¥.].
      ^)

こちらも枯れたプロジェクトとは言い難いため、特に Java 版のシリアライズ・デシリアラ
イズ実装にはバグが多数存在するため、使用には注意が必要である。

  4.8 ここまでのまとめ
上述した各種手法についてまとめる。
          データ形式               スキーマ定義    複数パッケージ   データの Java 以
                                                  外での使用
Serializable     バイナリ         不要        不可        不可
Deserializable   バイナリ         不要        不可        不可
JSONIC           テキスト(JSON)   必要(クラス)   不可        可
FlexJson         テキスト(JSON)   指定も可      不可        可
Protocol         バイナリ         必要(IDL)   不可        可
Buffers
Hadoop Avro      バイナリ    必要(JSON)  可         可
Message Pack     バイナリ    指定も可(独自書 可          可
                         式)
    データ形式:シリアライズ後のデータ形式
    スキーマ定義:シリアライズ・デシリアライズ時にスキーマ定義が必要かどうか
    複数パッケージ:複数のクラスを一度にシリアライズ・デシリアライズする事ができるか
    データの Java 以外での使用:Java 以外でもシリアライズデータを扱うことができるか。

5   各種シリアライズ手法による性能評価
今まで述べてきたシリアライズ手法各種について、性能評価を実施した。

    シリアライズ手法
     Java 標準 API
        Serializable
        Externalizable
     JSON 形式:JSONIC
     JSON 形式:FlexJson
     Hadoop Avro
     Message Pack
     Protocol Bufferes

    対象データ
     文字列(Hello World)
     文字列(1MB) ※ランダム
     数値(int)※ランダム
     数値(long)※ランダム
     数値(double)※ランダム
     配列(1KB の文字列      256 要素)※ランダム
     List(1KB の文字列    256 要素)※ランダム




                                  11
   Map(Key:256Byte の文字列/Value:int   1024 の要素)※ランダム
      クラス(Serializable 対応)
      クラス(Externalizable 対応)

  評価軸
   シリアライズ速度( s)
   デシリアライズ速度( s)
   シリアライズ後のデータサイズ(byte)

  テスト手法
   上記各手法を用いてデータのシリアライズ・デシリアライズをそれぞれ1万回くりかえし、
     結果の平均値を算出した
   ディスクの読み書き速度が測定に影響しないよう、シリアライズしたデータはメモリ内に格
     納し、メモリ内のデータをさらにデシリアライズした。

  テスト環境
   CPU:Core2Quad(Intel(R) Xeon(R) CPU E5540 @ 2.53GHz)
   Memory:4GB

なお、シリアライズ手法によっては、特定のデータ形式が扱えないものも存在するため、それらにつ
いては評価対象外としている。
(数値としては「0」扱いとしている。後述の詳細結果内では「-」表記としている)
たとえば Java 標準 API については、「クラス(Externalizable 対応)」のみ Externalizable クラ
スとして実装したものに対して評価し、それ以外は Serializable 対応クラスにて評価を行った。
JSONIC についてはシリアライズ後 JSON 記法に成り得ないデータ形式(単純な文字列や数値)
についてはシリアライズができないため未評価である。
また、Protocol Buffers については実装が特殊なため、「クラス(Serializable 対応)」のみの評価
となる。




                                  12
5.1   結果(シリアライズ)




                         Java標準API




5.2   結果(デシリアライズ)




                         Java標準API




                    13
5.3     結果(データサイズ)




                                                           Java標準API




    5.4  ここまでのまとめ
結論から言うと、Message Pack がシリアライズ速度、デシリアライズ速度、シリアライズ後のデータ
サイズ、全てにおいて最も優秀である。
Java 標準 API や Avro では、数値や文字列を Java のオブジェクトとして扱っているため、今回の
条件ではシリアライズ速度やデータサイズで損をしている部分があると思われるが、それを割り引い
ても Message Pack の優秀さが際立つ結果となった。

Protocol Buffers についてはクラスのシリアライズ・デシリアライズについてのみ評価を行ったが、
データサイズの小ささは群を抜いている。複雑な構造のクラスや、インスタンスが多くデータが肥大
するようなクラスの場合は強みを発揮すると思われる。

ただし本論では実装の汎用性や簡易性などを考慮して、Message Pack が一番使い勝手の良い
シリアライズ手法と判断する。

なお、上記グラフでは詳細な結果がわかりづらいため、本論末に詳細結果一覧を記載する。興味
の有る方は参照されたい。

6      圧縮アルゴリズムについて
以上、各種シリアライズ形式について述べてきたが、データの省サイズ化という観点から考えるとシ
リアライズデータのデータ構造の効率化だけでは物足りない部分もある。
そこで、シリアライズしたデータをさらに圧縮アルゴリズムにより圧縮化することで、どの程度の省サ
イズ化が果たせるか、検証を行った。
とはいえただ圧縮率が高いだけで圧縮・伸長速度が遅いアルゴリズム(bzip21等)では用途が制限
されてしまうため、
・ 圧縮率はほどほど
・ 圧縮・伸長速度が速い
というアルゴリズムを中心に調査した。

1   http://www.bzip.org/




                            14
今回は、一般的な圧縮アルゴリズムとして Deflate アルゴリズム、圧縮伸長速度が速いことで一部
注目を集めている QuickLZ アルゴリズムを評価対象として、性能比較を行った。

なお、以降はシリアライズ手法については Message Pack のみを対象として話を進める。

    6.1   Deflate アルゴリズム
Deflate1はフィル・カッツが開発した辞書式による圧縮アルゴリズムで、非常に多岐に渡って使用さ
れている2。
Deflate では、辞書式圧縮方式として著名な LZ773と、頻出データに小さいデータを割り当てる圧
縮方式であるハフマン符号化4(動的ハフマン符号化)を組み合わせることで、高圧縮でかつ圧縮・
伸長速度が比較的速いアルゴリズムを実現している。
また、圧縮レベル(1~9)を任意で設定できるため、圧縮率と圧縮・伸長速度のトレードオフを使用
者が調節できるようになっていることも特徴である。

    6.2   QuickLZ アルゴリズム
QuickLZ5は、GPL ライセンスで公開されているオープンソースライブラリである。圧縮・伸長速度
の速さにこだわったアルゴリズムで、他の同種のアルゴリズムに比べても速度が優秀だとされている
(QuickLZ のサイトに掲載されているベンチマーク結果6では、他アルゴリズムよりも優秀である)

QuizkLZ は、レベル指定(1~3)により圧縮速度と伸長速度のトレードオフを調節できるようになっ
ている。レベル1だと圧縮速度優先(伸長速度はそれほど速くない)になり、レベル3だと伸長速度
優先となる。

7     圧縮アルゴリズムを用いたシリアライズの性能評価
Message Pack と各種圧縮アルゴリズムを用いて、シリアライズ・デシリアライズの性能評価を実施
した。

     シリアライズ手法
      Message Pack

     圧縮手法
      無圧縮
      Deflate
        圧縮・伸張速度優先(レベル1)
        圧縮率優先(レベル9)
        ハフマン符号化のみ
      QuickLZ
        圧縮速度優先(レベル1)


1   http://ja.wikipedia.org/wiki/Deflate
2   GZIP や ZIP などの圧縮形式や、HTTP 通信時の圧縮アルゴリズムとしても採用されている(GZIP 圧縮)。
    Apache では圧縮用のモジュールとして mod_deflate が標準で搭載されている。また zlib というライブラリも用意
    されており多くの Linux 系 OS には標準搭載されている。
3   http://ja.wikipedia.org/wiki/LZ77
4

    http://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%95%E3%83%9E%E3%83%B3%E7%AC%A6%E5
    %8F%B7
5   http://www.quicklz.com/
6   http://www.quicklz.com/bench.html を参照のこと




                                        15
   伸長速度優先(レベル3)

対象データ
 文字列(Hello World)
 文字列(1MB) ※ランダム
 数値(int)※ランダム
 数値(long)※ランダム
 数値(double)※ランダム
 List(1KB の文字列     256 要素)※ランダム
 Map(Key:256Byte の文字列/Value:int 1024 の要素)※ランダム

評価軸
 シリアライズ速度( s)
 デシリアライズ速度( s)
 シリアライズ後のデータサイズ(byte)

テスト手法
 上記各手法を用いてデータのシリアライズ・デシリアライズをそれぞれ1万回くりかえし、
   結果の平均値を算出した
 ディスクの読み書き速度が測定に影響しないよう、シリアライズしたデータはメモリ内に格
   納し、メモリ内のデータをさらにデシリアライズした。

テスト環境
 CPU:Core2Quad(Intel(R) Xeon(R) CPU E5540 @ 2.53GHz)
 Memory:4GB

7.1       結果(シリアライズ)




                               16
7.2   結果(デシリアライズ)




  7.3   結果(データサイズ)




    7.4  ここまでのまとめ
QuickLZ による圧縮を試みたが、無圧縮時に比べてもデータサイズの増減がなく、圧縮が行えて
なかった。QuickLZ では ASCII 文字の並びのデータについては圧縮が行われない傾向があり、
今回のような結果となっている。QuickLZ の圧縮率については次項で改めて評価する。
圧縮伸張の速度については、圧縮優先のレベル1の方が圧縮速度は速く、伸長優先のレベル3で
は逆の結果が現れている。こちらについては想定通りの結果であった。



                        17
Deflate アルゴリズムについては、レベル1とレベル9、ハフマン符号化の間で大きな差が確認でき
なかった。こちらも今回使用したデータの特性も影響していると考えられる。

なお、単純な数値データなど、サイズが小さいデータについては圧縮を行うと逆にデータサイズが
肥大化するため、数値等のデータについては圧縮を行うのは適切では無い。
また無圧縮の時に比べてシリアライズ・デシリアライズにおおよそ 10 倍くらい時間がかかるため、圧
縮効果とのトレードオフで採用を検討する必要がある。

なお、上記グラフでは詳細な結果がわかりづらいため、本論末に詳細結果一覧を記載する。興味
の有る方は参照されたい。

8     実データへの応用
実際のデータに対してシリアライズ+圧縮アルゴリズムを適用して、どの程度のデータ圧縮が実現
できるか、調査した。

    8.1    Twitter のクロールデータ
別件で定期的にクローリングしている Twitter のつぶやきデータを用いて検証を行った。
当該データは、Twitter の Streaming API(sample API)1から取得できるデータを定期的に獲得
し、MySQL に保存しているものである。
MySQL 上では擬似的に Key-Value Store のような形でデータを保存しており、Key は文字列
(varchar(255))、Value は JSON 形式の文字列(BLOB)として保存されている。
つぶやきデータは JSON 形式に変換された上で Value として保存されており、今回圧縮対象とし
たのもこの JSON のデータになる。

    8.1.1       データ圧縮
      データ件数
       約 180 万件(1,798,947 件)
      データサイズ
       約 750MB(751,423,568byte MySQL の MYD ファイルのみのサイズ)
       1レコードあたり平均長:417byte
      圧縮対象
       つぶやきデータ(JSON 形式)
           JSON Map 形式に変換した上で、シリアライズ(+圧縮)
      シリアライズ形式
       Message Pack
      圧縮アルゴリズム
       無圧縮
       Deflate(ハフマン符号化)
       QuickLZ(レベル1:圧縮速度優先)
      検証方法
       既存のデータを dump し、1レコードずつシリアライズ+圧縮処理を行った上で別のテー
          ブルに保存する。
       既存のデータとシリアライズデータとのデータサイズ比較は、MySQL の MYD ファイルの
          サイズ比較にて実施。

結果は以下のようになった。

1   http://apiwiki.twitter.com/Streaming-API-Documentation




                                                18
データサイズ



           元サイズ
                             +Deflate   +QuickLZ


元データを Message Pack 形式に変更することで、おおよそ 3/4 のサイズとなっている。
Message Pack+Deflate では、元のデータに比べて、おおよそ 2/3 のサイズとなっている。
JSON から Message Pack 形式に変更するだけでデータサイズをコンパクトにすることができるが、
さらにハフマン符号化などを行うことでデータの圧縮が可能であることが確認できた。

Message Pack をさらに QuickLZ で圧縮することでも更なる圧縮が行われたが、データの圧縮率
は非常に低かった(560.4MB 560.2MB)。Message Pack によりすでに効率的なデータ格納が
果たされているため、非冗長のデータに対する圧縮をスキップする傾向の強い QuickLZ での圧縮
はそれほど効果が無かったようである。

 8.1.2       デシリアライズ速度
上記シリアライズデータがどの程度の速度で復元できたか、調査した。
   データ件数
    約 180 万件(1,798,947 件)
   データサイズ
    無圧縮
        約 560MB(560,456,384 byte MySQL の MYD ファイルのみのサイズ)
        1レコードあたり平均超:311byte
    Deflate
        約 500MB(499,939,996 byte MySQL の MYD ファイルのみのサイズ)
        1レコードあたり平均長:277byte
    QuickLZ
        約 578MB(560,261,688 byte MySQL の MYD ファイルのみのサイズ)
        1レコードあたり平均長:311byte
   デシリアライズ形式
    Message Pack
   圧縮アルゴリズム
    無圧縮
    Deflate(ハフマン符号化)
    QuickLZ(レベル1:圧縮速度優先)
   検証方法
    シリアライズデータを全件 dump し、1レコードずつ伸長処理+デシリアライズを行う。
    1レコードあたりの復元速度の平均を測定。

結果としては以下のようになった。
                     デシリアライズ速度( s)      deserialize dytes / micro sec
Message Pack         25 s               12.44 byte/ s
Message Pack+Deflate 31 s               8.93 byte/ s




                            19
Message Pack+QuickLZ         19 s                         16.36 byte/ s

Message Pack 単体、Message Pack+Deflate、Message Pack+QuickLZ いずれも1レコード
あたり数十 s でのデシリアライズが行えた。非常に高負荷・高トラフィックのシステムでは微妙な数
値かもしれないが、たいていのシステムであれば許容範囲の数値と思われる。
上記のように、既存のシリアライズ形式と圧縮アルゴリズムを組み合わせることで、現実的な処理時
間でデータの圧縮が行えることが確認できた。

また、Deflate に比べて QuickLZ は圧縮率が低いが伸長速度は速い、という、仕様として言われ
ている通りの結果が確認できた。

適応する現場の要件に応じて採用するアルゴリズムを変える、というのが落とし所になると考えられ
る。Deflate アルゴリズムの圧縮・伸長速度で十分なのであれば当該アルゴリズムにてデータ圧縮
率を稼ぎ、何よりも速度重視の場合は Message Pack 単体で用いるか、圧縮が行われやすいデー
タ形式であれば QuickLZ を用いる、というケースが考えられる。

9   まとめと考察
Java の各種シリアライズ手法について調査した。調査の結果、Message Pack が他手法に比して
速度、データサイズの点で優秀であり、かつ実装も比較的容易であることが分かった。

データ圧縮手法について Deflate と QuickLZ を調査した。Deflate は QuickLZ に対して圧縮率
で優位であり、対して QuickLZ は圧縮・伸長速度で優位であることが確認できた。
応用として、Message Pack と Deflate、QuickLZ を組み合わせて Twitter のクロールデータの圧
縮を試みた。結果、それぞれ元データの 2/3~3/4 のサイズにデータが圧縮でき、伸長速度も数十
 s で、多くのシステムの場に現実的に適用可能であることが分かった。

今回の調査によりデータシリアライズ+圧縮のメリットの多さ・デメリットの少なさについて十分な裏
付けが得られたため、実際にいくつかのシステムに本手法を適用することを考えている。結果として
今まで以上にマシンリソースの有効活用が果たされることを期待している。


10 参考文献・URL
[1] オブジェクト直列化(Java)
http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/serialization/index.html
[2] JSONIC
http://jsonic.sourceforge.jp/
[3] FlexJson
http://flexjson.sourceforge.net/
[4] Protocol Buffers
http://code.google.com/intl/ja/apis/protocolbuffers/docs/overview.html
[5] Hadoop Avro
http://hadoop.apache.org/avro/
[6] Message Pack
http://sourceforge.jp/projects/msgpack/
[7] MessagePack for Java 作りかけリリース! - 古橋貞之の日記
http://d.hatena.ne.jp/viver/20100115/p1
[8] Protocol Bufferes は遅い - 古橋貞之の日記
http://d.hatena.ne.jp/viver/20081116/p1
[9] QuickLZ




                                           20
http://www.quicklz.com/
[10] ひけらかし会:辞書式圧縮
http://www.slideshare.net/moaikids/ss-2638826




                                        21
11 [詳細]各種シリアライズ手法による性能評価
   11.1   文字列(Hello World)



                                             Java標準API




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




                              Java標準API




              データサイズ


                  シリアライズ( s)          デシリアライズ( s)     データサイズ(byte)
Java 標準 API                     13               12              19
JSONIC                           -                -                -
FlexJson                        15             108               14
                               101               76              74
                                 9               15              13
                                 -                -                -

   11.2   文字列(1MB)



                                             Java標準API




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




                                     22
Java標準API




               データサイズ



                    シリアライズ( s)        デシリアライズ( s)     データサイズ(byte)
Java 標準 API                                    8047         1048589
JSONIC                          -                 -                -
FlexJson                    13611             20593         1048578
                             4281              2166         1048644
                             3235               720         1048581
                                -                 -                -

   11.3   数値(int)



                                             Java標準API




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




                             Java標準API




              データサイズ


                    シリアライズ( s)        デシリアライズ( s)     データサイズ(byte)
Java 標準 API                                      55              81
JSONIC                           -                -                -



                                     23
FlexJson                       15               98                9
                               89               65               62
                                5               17                5
                                -                -                -

   11.4    数値(long)



                                            Java標準API




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




                           Java標準API




              データサイズ


                  シリアライズ( s)         デシリアライズ( s)     データサイズ(byte)
Java 標準 API                                     55              82
JSONIC                          -                -                -
FlexJson                       17             122               19
                               95               68              68
                                5               17                9
                                -                -                -




                                    24
11.5   数値(double)



                                            Java標準API




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




                           Java標準API




              データサイズ


                  シリアライズ( s)         デシリアライズ( s)     データサイズ(byte)
Java 標準 API                                     53              84
JSONIC                          -                -                -
FlexJson                       20             125               18
                               99               73              69
                                5               17                9
                                -                -                -

   11.6   配列(1KB の文字列    256 要素)



                                            Java標準API




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




                                    25
Java標準API




              データサイズ




                 シリアライズ( s)         デシリアライズ( s)     データサイズ(byte)
Java 標準 API               1107               1520          265260
JSONIC                   16206               4751          265217
FlexJson                  3409               4575          265217
                          1337                904          264283
                             -                  -                -
                             -                  -                -

   11.7   List(1KB の文字列   256 要素)



                                           Java標準API




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




                            Java標準API




              データサイズ



                 シリアライズ( s)         デシリアライズ( s)     データサイズ(byte)
Java 標準 API               1236               1663          265274



                                 26
JSONIC                        16016             4676            265217
FlexJson                       3159             5190            265217
                               1355              933            264283
                                882              640            265219
                                  -                -                 -

   11.8    Map(Key:256Byte の文字列/Value:int   1024 の要素)



                                              Java標準API




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




                                Java標準API




               データサイズ



                   シリアライズ( s)          デシリアライズ( s)      データサイズ(byte)
Java 標準 API                 1704                2354           275605
JSONIC                     18224                5611           276463
FlexJson                    1859                6505           276463
                            1249                1248           269334
                            1031                1480           270338
                               -                   -                 -




                                      27
11.9   クラス(Serializable 対応)



                                                Java標準API




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




                                 Java標準API




              データサイズ


                  シリアライズ( s)             デシリアライズ( s)     データサイズ(byte)
Java 標準 API                        24               47             116
JSONIC                             52               79              43
FlexJson                           38             154               92
                                  108             130              224
                                    -                -                -
                                   25               13              19

   11.10 クラス(Externalizable 対応)



                                                Java標準API




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




                                        28
Java標準API




              データサイズ


                  シリアライズ( s)          デシリアライズ( s)     データサイズ(byte)
Java 標準 API                     22               43              99
JSONIC                          42               71              43
FlexJson                         -                -                -
                               109             133              238
                                 -                -                -
                                 -                -                -

12 [詳細] 圧縮アルゴリズムを用いたシリアライズの性能評価
   12.1   文字列(Hello World)




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




                データサイズ


                  シリアライズ( s)          デシリアライズ( s)     データサイズ(byte)




                                     29
無圧縮                             9               15              13
deflate(1)                     82              965              21
deflate(9)                     82              984              21
deflate(huffman)               83             1137              21
quicklz(1)                    276             1125              26
quicklz(3)                    255              972              26

   12.2   文字列(1MB)




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




                   データサイズ



                   シリアライズ( s)        デシリアライズ( s)     データサイズ(byte)
無圧縮                         3235               720         1048581
deflate(1)                 77276              2092          788583
deflate(9)                 78841              2146          788583
deflate(huffman)           79523              2115          788583
quicklz(1)                 28580              4384         1048590
quicklz(3)                 79086              4099         1048590




                                    30
12.3   数値(int)




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




                   データサイズ


                    シリアライズ( s)          デシリアライズ( s)     データサイズ(byte)
無圧縮                                5               17               5
deflate(1)                        78             1052              13
deflate(9)                        73              969              13
deflate(huffman)                  74              961              13
quicklz(1)                       265             1112              17
quicklz(3)                       249             1000              18

   12.4   数値(long)




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




                                       31
データサイズ


                    シリアライズ( s)          デシリアライズ( s)     データサイズ(byte)
無圧縮                                5               17               9
deflate(1)                        75              989              17
deflate(9)                        75              976              17
deflate(huffman)                  76              957              17
quicklz(1)                       260             1098              22
quicklz(3)                       248              980              22

    12.5     数値(double)




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




                   データサイズ


                    シリアライズ( s)          デシリアライズ( s)     データサイズ(byte)
無圧縮                               5                17               9
deflate(1)                       75              989               17



                                       32
deflate(9)                       75              976              17
deflate(huffman)                 76              957              17
quicklz(1)                      260             1098              22
quicklz(3)                      248              980              22

   12.6   List(1KB の文字列     256 要素)




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




                   データサイズ


                   シリアライズ( s)          デシリアライズ( s)     データサイズ(byte)
無圧縮                            882               640          265219
deflate(1)                   22358              7556          199361
deflate(9)                   20893              7338          199362
deflate(huffman)             22305              7629          199362
quicklz(1)                    7466              2233          265228
quicklz(3)                   17957              2148          265228




                                      33
12.7   Map(Key:256Byte の文字列/Value:int   1024 の要素)




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




                   データサイズ


                   シリアライズ( s)       デシリアライズ( s)        データサイズ(byte)
無圧縮                         1031             1480             270338
deflate(1)                 22124             8172             207454
deflate(9)                 22199             8108             207455
deflate(huffman)           23816             8657             207454
quicklz(1)                  7845             3108             270347
quicklz(3)                 18737             2918             270347




                                   34

Mais conteúdo relacionado

Mais procurados

がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはJun-ichi Sakamoto
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)NTT DATA Technology & Innovation
 
Apache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once SemanticsApache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once SemanticsYoshiyasu SAEKI
 
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) Hironobu Isoda
 
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...Shinji Takao
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較Akihiro Suda
 
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26Yahoo!デベロッパーネットワーク
 
単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介AdvancedTechNight
 
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGoogle Cloud Platform - Japan
 
Java EE から Quarkus による開発への移行について
Java EE から Quarkus による開発への移行についてJava EE から Quarkus による開発への移行について
Java EE から Quarkus による開発への移行についてShigeru Tatsuta
 
マイクロサービスに至る歴史とこれから - XP祭り2021
マイクロサービスに至る歴史とこれから - XP祭り2021マイクロサービスに至る歴史とこれから - XP祭り2021
マイクロサービスに至る歴史とこれから - XP祭り2021Yusuke Suzuki
 
クラスローダーについて
クラスローダーについてクラスローダーについて
クラスローダーについてSuguru ARAKAWA
 
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGoogle Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGoogle Cloud Platform - Japan
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Akihiro Suda
 
Git超入門(ハンズオン).pdf
Git超入門(ハンズオン).pdfGit超入門(ハンズオン).pdf
Git超入門(ハンズオン).pdf憲昭 村田
 
ワタシはSingletonがキライだ
ワタシはSingletonがキライだワタシはSingletonがキライだ
ワタシはSingletonがキライだTetsuya Kaneuchi
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with KarateTakanori Suzuki
 
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기SeungYong Oh
 

Mais procurados (20)

がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
Mavenの真実とウソ
Mavenの真実とウソMavenの真実とウソ
Mavenの真実とウソ
 
Apache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once SemanticsApache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once Semantics
 
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
 
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
 
単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介
 
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
 
Java EE から Quarkus による開発への移行について
Java EE から Quarkus による開発への移行についてJava EE から Quarkus による開発への移行について
Java EE から Quarkus による開発への移行について
 
マイクロサービスに至る歴史とこれから - XP祭り2021
マイクロサービスに至る歴史とこれから - XP祭り2021マイクロサービスに至る歴史とこれから - XP祭り2021
マイクロサービスに至る歴史とこれから - XP祭り2021
 
クラスローダーについて
クラスローダーについてクラスローダーについて
クラスローダーについて
 
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGoogle Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
Git超入門(ハンズオン).pdf
Git超入門(ハンズオン).pdfGit超入門(ハンズオン).pdf
Git超入門(ハンズオン).pdf
 
ワタシはSingletonがキライだ
ワタシはSingletonがキライだワタシはSingletonがキライだ
ワタシはSingletonがキライだ
 
NGINXをBFF (Backend for Frontend)として利用した話
NGINXをBFF (Backend for Frontend)として利用した話NGINXをBFF (Backend for Frontend)として利用した話
NGINXをBFF (Backend for Frontend)として利用した話
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate
 
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
 

Semelhante a Javaにおけるデータシリアライズと圧縮

イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情takezoe
 
cassandra調査レポート
cassandra調査レポートcassandra調査レポート
cassandra調査レポートAkihiro Kuwano
 
Elasticsearch勉強会#44 20210624
Elasticsearch勉強会#44 20210624Elasticsearch勉強会#44 20210624
Elasticsearch勉強会#44 20210624Tetsuya Sodo
 
社内勉強会02 シリアライズ[公開用]
社内勉強会02 シリアライズ[公開用]社内勉強会02 シリアライズ[公開用]
社内勉強会02 シリアライズ[公開用]Keme Sato
 
Sql server data store data access internals
Sql server data store data access internalsSql server data store data access internals
Sql server data store data access internalsMasayuki Ozawa
 
Rユーザのためのspark入門
Rユーザのためのspark入門Rユーザのためのspark入門
Rユーザのためのspark入門Shintaro Fukushima
 
Django Rest Frameworkでお手軽にREST APIを作る
Django Rest Frameworkでお手軽にREST APIを作るDjango Rest Frameworkでお手軽にREST APIを作る
Django Rest Frameworkでお手軽にREST APIを作るMatsuo Keita
 
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~JustSystems Corporation
 
Introduction to windows azure storage
Introduction to windows azure storage Introduction to windows azure storage
Introduction to windows azure storage Takekazu Omi
 
[ウェビナー] Build 2018 アップデート ~ データ プラットフォーム/IoT編 ~
[ウェビナー] Build 2018 アップデート ~ データ プラットフォーム/IoT編 ~[ウェビナー] Build 2018 アップデート ~ データ プラットフォーム/IoT編 ~
[ウェビナー] Build 2018 アップデート ~ データ プラットフォーム/IoT編 ~Naoki (Neo) SATO
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
Linux/DB Tuning (DevSumi2010, Japanese)
Linux/DB Tuning (DevSumi2010, Japanese)Linux/DB Tuning (DevSumi2010, Japanese)
Linux/DB Tuning (DevSumi2010, Japanese)Yoshinori Matsunobu
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaKazuhiro Sera
 
Css2014 ruo ando_2014-10-23-01
Css2014 ruo ando_2014-10-23-01Css2014 ruo ando_2014-10-23-01
Css2014 ruo ando_2014-10-23-01Ruo Ando
 
MySQLのパフォーマンスの話
MySQLのパフォーマンスの話MySQLのパフォーマンスの話
MySQLのパフォーマンスの話Tetsuro Ikeda
 

Semelhante a Javaにおけるデータシリアライズと圧縮 (20)

イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情
 
cassandra調査レポート
cassandra調査レポートcassandra調査レポート
cassandra調査レポート
 
Elasticsearch勉強会#44 20210624
Elasticsearch勉強会#44 20210624Elasticsearch勉強会#44 20210624
Elasticsearch勉強会#44 20210624
 
社内勉強会02 シリアライズ[公開用]
社内勉強会02 シリアライズ[公開用]社内勉強会02 シリアライズ[公開用]
社内勉強会02 シリアライズ[公開用]
 
Sql server data store data access internals
Sql server data store data access internalsSql server data store data access internals
Sql server data store data access internals
 
Rユーザのためのspark入門
Rユーザのためのspark入門Rユーザのためのspark入門
Rユーザのためのspark入門
 
Django Rest Frameworkでお手軽にREST APIを作る
Django Rest Frameworkでお手軽にREST APIを作るDjango Rest Frameworkでお手軽にREST APIを作る
Django Rest Frameworkでお手軽にREST APIを作る
 
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
 
Introduction to windows azure storage
Introduction to windows azure storage Introduction to windows azure storage
Introduction to windows azure storage
 
[ウェビナー] Build 2018 アップデート ~ データ プラットフォーム/IoT編 ~
[ウェビナー] Build 2018 アップデート ~ データ プラットフォーム/IoT編 ~[ウェビナー] Build 2018 アップデート ~ データ プラットフォーム/IoT編 ~
[ウェビナー] Build 2018 アップデート ~ データ プラットフォーム/IoT編 ~
 
Spock's world
Spock's worldSpock's world
Spock's world
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
named_scope more detail
named_scope more detailnamed_scope more detail
named_scope more detail
 
Linux/DB Tuning (DevSumi2010, Japanese)
Linux/DB Tuning (DevSumi2010, Japanese)Linux/DB Tuning (DevSumi2010, Japanese)
Linux/DB Tuning (DevSumi2010, Japanese)
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
 
Css2014 ruo ando_2014-10-23-01
Css2014 ruo ando_2014-10-23-01Css2014 ruo ando_2014-10-23-01
Css2014 ruo ando_2014-10-23-01
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
Java class design
Java class designJava class design
Java class design
 
MySQLのパフォーマンスの話
MySQLのパフォーマンスの話MySQLのパフォーマンスの話
MySQLのパフォーマンスの話
 
20121215 DevLOVE2012 Mahout on AWS
20121215 DevLOVE2012 Mahout on AWS20121215 DevLOVE2012 Mahout on AWS
20121215 DevLOVE2012 Mahout on AWS
 

Mais de moai kids

中国最新ニュースアプリ事情
中国最新ニュースアプリ事情中国最新ニュースアプリ事情
中国最新ニュースアプリ事情moai kids
 
FluentdとRedshiftの素敵な関係
FluentdとRedshiftの素敵な関係FluentdとRedshiftの素敵な関係
FluentdとRedshiftの素敵な関係moai kids
 
Twitterのsnowflakeについて
TwitterのsnowflakeについてTwitterのsnowflakeについて
Twitterのsnowflakeについてmoai kids
 
Programming Hive Reading #4
Programming Hive Reading #4Programming Hive Reading #4
Programming Hive Reading #4moai kids
 
Programming Hive Reading #3
Programming Hive Reading #3Programming Hive Reading #3
Programming Hive Reading #3moai kids
 
"Programming Hive" Reading #1
"Programming Hive" Reading #1"Programming Hive" Reading #1
"Programming Hive" Reading #1moai kids
 
Casual Compression on MongoDB
Casual Compression on MongoDBCasual Compression on MongoDB
Casual Compression on MongoDBmoai kids
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDBmoai kids
 
Hadoop Conference Japan 2011 Fallに行ってきました
Hadoop Conference Japan 2011 Fallに行ってきましたHadoop Conference Japan 2011 Fallに行ってきました
Hadoop Conference Japan 2011 Fallに行ってきましたmoai kids
 
HBase本輪読会資料(11章)
HBase本輪読会資料(11章)HBase本輪読会資料(11章)
HBase本輪読会資料(11章)moai kids
 
snappyについて
snappyについてsnappyについて
snappyについてmoai kids
 
第四回月次セミナー(公開版)
第四回月次セミナー(公開版)第四回月次セミナー(公開版)
第四回月次セミナー(公開版)moai kids
 
第三回月次セミナー(公開版)
第三回月次セミナー(公開版)第三回月次セミナー(公開版)
第三回月次セミナー(公開版)moai kids
 
Pythonで自然言語処理
Pythonで自然言語処理Pythonで自然言語処理
Pythonで自然言語処理moai kids
 
HandlerSocket plugin Client for Javaとそれを用いたベンチマーク
HandlerSocket plugin Client for Javaとそれを用いたベンチマークHandlerSocket plugin Client for Javaとそれを用いたベンチマーク
HandlerSocket plugin Client for Javaとそれを用いたベンチマークmoai kids
 
Yammer試用レポート(公開版)
Yammer試用レポート(公開版)Yammer試用レポート(公開版)
Yammer試用レポート(公開版)moai kids
 
掲示板時間軸コーパスを用いたワードトレンド解析(公開版)
掲示板時間軸コーパスを用いたワードトレンド解析(公開版)掲示板時間軸コーパスを用いたワードトレンド解析(公開版)
掲示板時間軸コーパスを用いたワードトレンド解析(公開版)moai kids
 
中国と私(仮題)
中国と私(仮題)中国と私(仮題)
中国と私(仮題)moai kids
 
不自然言語処理コンテストLT資料
不自然言語処理コンテストLT資料不自然言語処理コンテストLT資料
不自然言語処理コンテストLT資料moai kids
 
n-gramコーパスを用いた類義語自動獲得手法について
n-gramコーパスを用いた類義語自動獲得手法についてn-gramコーパスを用いた類義語自動獲得手法について
n-gramコーパスを用いた類義語自動獲得手法についてmoai kids
 

Mais de moai kids (20)

中国最新ニュースアプリ事情
中国最新ニュースアプリ事情中国最新ニュースアプリ事情
中国最新ニュースアプリ事情
 
FluentdとRedshiftの素敵な関係
FluentdとRedshiftの素敵な関係FluentdとRedshiftの素敵な関係
FluentdとRedshiftの素敵な関係
 
Twitterのsnowflakeについて
TwitterのsnowflakeについてTwitterのsnowflakeについて
Twitterのsnowflakeについて
 
Programming Hive Reading #4
Programming Hive Reading #4Programming Hive Reading #4
Programming Hive Reading #4
 
Programming Hive Reading #3
Programming Hive Reading #3Programming Hive Reading #3
Programming Hive Reading #3
 
"Programming Hive" Reading #1
"Programming Hive" Reading #1"Programming Hive" Reading #1
"Programming Hive" Reading #1
 
Casual Compression on MongoDB
Casual Compression on MongoDBCasual Compression on MongoDB
Casual Compression on MongoDB
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
Hadoop Conference Japan 2011 Fallに行ってきました
Hadoop Conference Japan 2011 Fallに行ってきましたHadoop Conference Japan 2011 Fallに行ってきました
Hadoop Conference Japan 2011 Fallに行ってきました
 
HBase本輪読会資料(11章)
HBase本輪読会資料(11章)HBase本輪読会資料(11章)
HBase本輪読会資料(11章)
 
snappyについて
snappyについてsnappyについて
snappyについて
 
第四回月次セミナー(公開版)
第四回月次セミナー(公開版)第四回月次セミナー(公開版)
第四回月次セミナー(公開版)
 
第三回月次セミナー(公開版)
第三回月次セミナー(公開版)第三回月次セミナー(公開版)
第三回月次セミナー(公開版)
 
Pythonで自然言語処理
Pythonで自然言語処理Pythonで自然言語処理
Pythonで自然言語処理
 
HandlerSocket plugin Client for Javaとそれを用いたベンチマーク
HandlerSocket plugin Client for Javaとそれを用いたベンチマークHandlerSocket plugin Client for Javaとそれを用いたベンチマーク
HandlerSocket plugin Client for Javaとそれを用いたベンチマーク
 
Yammer試用レポート(公開版)
Yammer試用レポート(公開版)Yammer試用レポート(公開版)
Yammer試用レポート(公開版)
 
掲示板時間軸コーパスを用いたワードトレンド解析(公開版)
掲示板時間軸コーパスを用いたワードトレンド解析(公開版)掲示板時間軸コーパスを用いたワードトレンド解析(公開版)
掲示板時間軸コーパスを用いたワードトレンド解析(公開版)
 
中国と私(仮題)
中国と私(仮題)中国と私(仮題)
中国と私(仮題)
 
不自然言語処理コンテストLT資料
不自然言語処理コンテストLT資料不自然言語処理コンテストLT資料
不自然言語処理コンテストLT資料
 
n-gramコーパスを用いた類義語自動獲得手法について
n-gramコーパスを用いた類義語自動獲得手法についてn-gramコーパスを用いた類義語自動獲得手法について
n-gramコーパスを用いた類義語自動獲得手法について
 

Último

スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 

Último (9)

スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 

Javaにおけるデータシリアライズと圧縮

  • 1. 研究課題:Java におけるシリアライズとデータ圧縮 新規開発局 プログラマ 大平哲也 1
  • 2. 1 はじめに CGM サイトなど、データが無尽蔵に増える種類のサイトを運営する際は、増え続けるデータの扱 いが重要である。一つの対応として、データを永続化(直列化、シリアライズ)する際にデータのサ イズを減らすことでデータ転送量やディスク容量の削減を行い、パフォーマンスを維持したりリソー スを有効活用する方法が考えられるが、ただ圧縮をすれば良い訳ではなく、復元時の速度や、プ ログラムからの扱いやすさも現実的な問題としては重要な事項になる。 まとめると、データのシリアライズ方式の検討は以下の観点における検討が大事になる。 ・ データの省サイズ化 ・ シリアライズ・デシリアライズの速度 ・ プログラミング側からみた構造の柔軟性、扱いやすさ そこで、Java におけるシリアライズ手法について調査した。 本論では、Java における各種シリアライズ手法を調査ならびに比較検証することにより、上記3点 をバランスよく満たす、システムに適用しやすいシリアライズ手法を見出すことを目的とする。 2 動機 2.1 Java シリアライズの遅さ Java は標準の言語機構においてオブジェクトインスタンスのシリアライズをサポートしている1という 優秀な言語ではあるが、非常に汎用的に作られているため単純なデータ永続化を果たしたい時に は冗長すぎる仕様がネックになるケースがあり、シリアライズ・デシリアライズの遅さ、ならびにシリア ライズデータの大きさが問題となる。(他手法との性能比較についての詳細は後述する) たとえば、Java RMI などの RPC 処理の際、デフォルトでは Serializable インターフェースを継承 したクラスをシリアライズ・デシリアライズしてやりとりを行うことになるが、単純なデータ構造のデータ を Java シリアライズそのまま用いて実装すると、他手法のシリアライズ形式を用いる際よりもパフォ ーマンス的に問題が発生することが考えられ、高負荷、高トラフィックなシステムであればある程こ のデメリットは大きくなる。 2.2 優秀な他手法の存在 近年は、多言語に対応可能でかつ高速・高機能なシリアライズ・デシリアライズ機構が多く世の中 に知られるようになっている。具体的には Google の Protocol Buffers2 、Hadoop の Hadoop Avro3、筑波大学の古橋貞之氏が製作した Message Pack4などである。 それぞれ手法ごとに機能的、性能的な特徴があるが、Java のシリアライズ機構との性能比較を実 際に行い、各手法のメリット・デメリットを把握したいと考えた。 3 本論の流れ まず、各種シリアライズ手法を概観する。 今回は Java の標準 API(Serializable、Externalizable)、JSON 形式へのシリアライズツール (JSONIC、FlexJson)、Protocol Buffers、Hadoop Avro、Message Pack を対象とした。 その上で、それぞれの手法におけるシリアライズ・デシリアライズのパフォーマンスを調査し、比較し た。今回はシリアライズ速度、デシリアライズ速度、シリアライズ後のデータサイズ、ならびに実装の 1 http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3 %82%BA なお他言語では Ruby では Marshal クラス、Python では Pickling により言語機構によりシリアライズがサポー トされている。 2 http://code.google.com/intl/ja/apis/protocolbuffers/docs/overview.html 3 http://hadoop.apache.org/avro/ 4 http://sourceforge.jp/projects/msgpack/ 2
  • 3. しやすさを評価軸とした。また、データ圧縮アルゴリズムを用いた際のパフォーマンスとデータサイ ズについても合わせて調査した。 そして最後に、調査結果を基に BtoC サイト、CGM サイトなどに適用しやすい組み合わせについ てまとめる。 4 各種シリアライズ手法 4.1 Java 標準 API:Serializable Java にて、オブジェクトインスタンスのシリアライズが必要な場合は、シリアライズ該当クラスにて java.io.Serializable1インターフェースを継承する。 これだけで、そのクラスはシリアライズ対応クラスとなる。 import java.io.Serializable; public class SerializableObject implements Serializable { private String name; //シリアライズのとき保存される。 static String staticField; //クラス変数は無視される。 private transient int hashCode; //transient キーワードが付いたフィールドは無視 される。 //シリアライズしたいクラスの実装... }2 実際のデータシリアライズ・デシリアライズを行う処理は自分で実装する必要がある。これらの処理 は Java RMI を用いる場合は Java RMI 機構が自動的に対応する。 import java.io.FileOutputStream; import java.io.OutputStream; import java.io.ObjectOutputStream; //... SerializableObject object = new SerializableObject(); OutputStream outputStream = new FileOutputStream("serializableObject.obj"); ObjectOutputStream objectOutputStream= new ObjectOutputStream(outputStream); objectOutputStream.writeObject(object);3 実際シリアライズされたデータは以下のようなものになる。以下はシリアライズデータをバイナリエデ ィタで閲覧したものである。 なお仕様については SUN の公式ドキュメントが詳しい4。 ac ed 00 05 73 72 00 0d 74 65 73 74 2e 54 65 73 1 http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/io/Serializable.html 2 http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3 %82%BA#Serializable より引用 3 http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3 %82%BA#.E3.83.90.E3.82.A4.E3.83.8A.E3.83.AA.E3.83.95.E3.82.A1.E3.82.A4.E3.83.AB.E3.81.AB. E3.82.B7.E3.83.AA.E3.82.A2.E3.83.A9.E3.82.A4.E3.82.BA より引用 4 http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/serialization/index.html 3
  • 4. 74 42 65 61 6e 20 e9 e2 62 c4 df 79 42 02 00 03 4a 00 02 69 64 4c 00 04 74 69 6d 65 74 00 10 4c 6a 61 76 61 2f 75 74 69 6c 2f 44 61 74 65 3b 4c 00 05 76 61 6c 75 65 74 00 12 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 78 70 00 00 00 00 00 00 00 01 73 72 00 0e 6a 61 76 61 2e 75 74 69 6c 2e 44 61 74 65 68 6a 81 01 4b 59 74 19 03 00 00 78 70 77 08 00 00 01 27 74 e6 d2 3c 78 74 00 04 74 65 73 74 (....sr..test.Tes tBean ..b..yB... J..idL..timet..L java/util/Date;L ..valuet..Ljava/ lang/String;xp.. ......sr..java.u til.Datehj..KYt. ...xpw....'t..<x t..test) 先頭の「ac ed」はシリアライズ形式を示すマジックナンバー。「00 05」は Java のバージョン番号と なる。以降オブジェクトの定義や変数の定義、変数の値などが埋め込まれている。 ヘッダ情報やオブジェクトの定義の情報が含まれているため、単純にデータのみを構造化してシリ アライズする手法よりもデータサイズが冗長となる。 4.2 Java 標準 API:Externalizable Java には、シリアライズデータフォーマットを自分で定義することができる API、Externalizable1 が用意されている。これを用いると、必要最低限な情報だけシリアライズすることも可能であり、デー タサイズやシリアライズ・デシリアライズ速度の向上を果たすことも可能である。 Externalizable にてシリアライズを行いたい場合は、該当クラスにて java.io.Externalizable イン ターフェースを継承した上で、必要なメソッド(writeExternal、readExternal)を実装する必要が ある。 import java.io.Externalizable; import java.io.ObjectOutput; import java.io.ObjectInput; public class SerializableObject implements Externalizable { private String name; //writeExternal(ObjectOutput)で指定されているため保存さ れるフィールド。 private int id; //無視される。 private int hashCode; //writeExternal(ObjectOutput)で指定されているため保存さ れるフィールド。 //Externalizable で定義されているメソッドをオーバーライド。 //保存したいフィールドを指定する。 @Override public void writeExternal(ObjectOutput out) { out.writeChars(this.name); 1 http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/io/Externalizable.html 4
  • 5. out.writeInt(this.hashCode); } //復元したいフィールドを指定する。 @Override public void readExternal(ObjectInput in) { this.name = in.readLine(); this.hasoCode = in.readInt(); } //シリアライズしたいクラスの実装 }1 シリアライズ、デシリアライズを行う処理の実装方法は、Serializable を用いた時と同様である。 4.1 で用いたクラスと同じもの(厳密にはクラス名が異なる2)を Externalizable にてシリアライズした ものが以下となる。 ac ed 00 05 73 72 00 1b 74 65 73 74 2e 45 78 74 65 72 6e 61 6c 69 7a 61 62 6c 65 54 65 73 74 42 65 61 6e a3 be c9 30 53 4a 7a f8 0c 00 00 78 70 77 08 00 00 00 00 00 00 00 01 74 00 04 74 65 73 74 73 72 00 0e 6a 61 76 61 2e 75 74 69 6c 2e 44 61 74 65 68 6a 81 01 4b 59 74 19 03 00 00 78 70 77 08 00 00 01 27 74 e6 d3 af 78 78 (....sr..test.Ext ernalizableTestB ean...0SJz....xp w.........t..tes tsr..java.util.D atehj..KYt....xp w....'t...xx) 先頭のヘッダ情報や、オブジェクトの定義については Serializable と同様に存在するが、それ以 降のデータの定義が最低限のもののみ出力されているため、Serializable に比べてデータサイズ が小さくなっている。 4.3 JSON 形式:JSONIC 構造化されたデータのテキストシリアライズ方式としては、近年は JSON3 形式が普及し、とくに BtoC サイトなどでは一般化している。 理由としては簡潔で直感的なデータ構造記法や、RFC に定義されている4など仕様の堅牢化、ライ ブラリの充実などが上げられる。 1 http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3 %82%BA#Externalizable より引用 2 4.1 では「test.TestBean(74 65 73 74 2e 54 65 73 74 42 65 61 6e)、4.2 では 」 「test.ExternalizableTestBean (74 65 73 74 2e 45 78 74 65 72 6e 61 6c 69 7a 61 62 6c 65 54 65 73 74 42 65 61 6e) 」を使用している。 3 http://ja.wikipedia.org/wiki/JavaScript_Object_Notation 4 http://www.rfc-editor.org/rfc/rfc4627.txt 5
  • 6. テキストシリアライズ手法としては他に XML1や YAML2などが存在するが、XML はスキーマ定義 が厳格に行える一方スキーマレスでも十分な軽いデータを扱うには冗長すぎる点がある。YAML については JSON と同様の軽さがあるが、JSON 程一般化していない。 そのため、ここでは JSON のみを対象とし、まずは JSON の Java 用シリアライズライブラリとして高 機能な JSONIC3について触れる。 JSONIC は Apache Lisence Version2.0 で提供されているオープンソースライブラリである。 シリアライズ・デシリアライズの記述が以下のように極めてシンプルに行えることが特徴である。 import net.arnx.jsonic.JSON; // POJO を JSON に変換します String text = JSON.encode(new Hoge()); // JSON を POJO に変換します Hoge hoge = JSON.decode(text, Hoge.class);4 出力形式は以下のような純粋な JSON 形式となり、クラス名などのメタ情報は含まれない。 それ故にデータ構造としては簡潔ではあるがデシリアライズ時には復元先のオブジェクトの明示的 な指定が必須になる。(シリアライズデータの情報のみから復元することはできない) {"id":1,"time":1268976636047,"value":"test"} 記述が簡便であることと高機能であることがメリットだが、データのシリアライズ等に Apache Commons の BeanUtils5を多用しており、必ずしも処理は高速では無い。 また、出力内容が JSON 形式になることを前提としているため、文字列のみや数値のみのデータ など、JSON 形式に成り得ないデータのシリアライズが出来ない仕様になっているので注意が必要 である。 4.4 JSON 形式:FlexJson FlexJson も JSONIC と同様 Apache Lisence Version 2.0 で公開されているオープンソースライ ブラリである。JSONIC と比べるとシリアライズデータにメタ情報(クラス名)が含まれ若干冗長であ ること、いくつかのバグが散見されるなどの問題もあるが、JSONIC に比べて高速にシリアライズが 行えるので紹介する。 シリアライズ・デシリアライズの記述は以下のようになる。 T obj; String json = new JSONSerializer().serialize(obj); T deserialized = new JSONDeserializer<T>().deserialize(json); クラスの一階層だけをシリアライズ(Shallow Serialize)/全てのデータをシリアライズ(Deep Serialize)したり、特定の名前空間の変数を include/exclude することができるのが FlexJson の 特徴である。また実装上もリフレクションを出来るだけ用いない工夫が見られる。 シリアライズ後のデータは以下のようになる。 1 http://ja.wikipedia.org/wiki/Extensible_Markup_Language 2 http://ja.wikipedia.org/wiki/YAML 3 http://jsonic.sourceforge.jp/ 4 http://jsonic.sourceforge.jp/ より引用 5 http://commons.apache.org/beanutils/ 6
  • 7. {"class":"test.TestBean","id":1,"time":1268976636560,"value":"test"} 4.5 Protocol Buffers Protocol Buffers は Google が BigTable などの社内のシステムに用いているとされる、データシリ アライズフォーマットと、そのデータの RPC 通信を行うためのフレームワークである。2008 年の7月 に Apache Lisence Version 2.0 のオープンソースプロジェクトとして外部に公開された。 Protocol Buffers は IDL1と呼ばれる独自 DSL 言語を基に各種プログラム言語用のソースコード を自動生成できることが特徴である。IDL 定義文は以下のようなものである。 package serializable.protobuf; message TestBean{ required int32 id = 1; required string value = 2; required int64 time = 3; } 上記を拡張子.proto として保存し、コード生成用のコマンドを実行すると各種言語向けのデータ操 作用プログラムファイルが自動生成される。 protoc --java_out=. --cpp_out=. --python_out=. ProtobufTestBean.proto 上記は、proto ファイルを基に Java、C++、Python のソースコードを自動生成する際のコマンドで ある。 生成されるソースコードは自動生成という事もあってか非常に冗長で、上記 proto ファイルの場合 Java で 422 行、C++でヘッダとソースを合わせて 652 行、Python で 67 行となった。 データのシリアライズ・デシリアライズ処理は自動生成コードで堅牢に行われるためか、シリアライズ されるデータ形式は非常にシンプルで無駄が無いものになっている。 4.3、4.4 と同じデータ構造を持つクラスをシリアライズした結果が以下になる。 08 01 12 04 74 65 73 74 18 f6 e2 b3 e1 06 (....test......) データは非常にシンプルで省サイズ化が可能であるが、生成コードにクセがあり、既存のシステム に導入するためには Protocol Buffers 向けに実装を作り直すことが必要となる。 4.6 Hadoop Avro Hadoop Avro は、分散並列処理フレームワークとして著名な Hadoop プロジェクト2のサブプロジェ クトとして、Hadoop 創始者の Doug. Cutting 氏によって 2009 年4月に立ち上げられた3新しいプ ロジェクトである。 Hadoop における RPC 処理や、 サブプロジェクトである Hadoop Pig4、 Hive5などでのシリ アライズ形式、RPC 形式を統一する、という目的で立ち上げられたようである。 1 http://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3 %83%BC%E3%82%B9%E8%A8%98%E8%BF%B0%E8%A8%80%E8%AA%9E 2 http://hadoop.apache.org/ 3 http://markmail.org/message/7cgrwoc4er4mr3bp 4 http://hadoop.apache.org/pig/ 5 http://hadoop.apache.org/hive/ 7
  • 8. 非常に多機能なことと、 ドキュメントが皆無であることから全体像は詳述できないが、ここ ではデータのシリアライズ方式についてのみ述べる。 Avro では、JSON 形式で記述したスキーマ定義を基にデータのシリアライズ、デシリアラ イズを行う。たとえば配列形式でシリアライズを行いたい場合は {"type": "array", "items": "string"} のような形で定義する。 なおスキーマ定義は Java クラスから自動生成することも可能である。 以下はシリアライズ時の処理である。 DataFileWriter<T> writer = null; Schema schema = null; if(schemastr != null){ schema = Schema.parse(schemastr); }else if(clazz != null){ ReflectData reflect = ReflectData.get(); schema = reflect.getSchema(clazz); } try{ writer = new DataFileWriter<T>(new ReflectDatumWriter<T>(schema)); writer.create(schema, out); writer.append(obj); writer.sync(); }finally{ if(writer != null) writer.close(); } 上記ソースでは、JSON 定義がある時は「Schema.parse」メソッドによりスキーマを生成 し、ない時は「ReflectData」インスタンスを用いて対象クラスからスキーマを生成してい る。 デシリアライズ時は以下のような処理になる。 DataFileStream<T> stream = null; Schema schema = null; if(schemastr != null){ schema = Schema.parse(schemastr); }else if(clazz != null){ ReflectData reflect = ReflectData.get(); schema = reflect.getSchema(clazz); } try{ stream = new DataFileStream<T>(is, new ReflectDatumReader<T>(schema)); return stream.next(); }finally{ if(stream != null) 8
  • 9. stream.close(); } 上記では一つのクラスファイルを前提とした処理になっているが、 複数のクラスをまとめて シリアライズ・デシリアライズできることが Avro の一つの特徴である。 シリアライズしたデータは以下のようになる。 JSON によるスキーマ定義情報もシリアライズデータの中に含まれるため、やや冗長にな っている。ただし、シリアライズ・デシリアライズ速度は優秀である。 4f 62 6a 01 02 16 61 76 72 6f 2e 73 63 68 65 6d 61 ca 02 7b 22 74 79 70 65 22 3a 22 72 65 63 6f 72 64 22 2c 22 6e 61 6d 65 22 3a 22 50 72 69 6d 69 74 69 76 65 54 65 73 74 42 65 61 6e 22 2c 22 6e 61 6d 65 73 70 61 63 65 22 3a 22 74 65 73 74 22 2c 22 66 69 65 6c 64 73 22 3a 5b 7b 22 6e 61 6d 65 22 3a 22 69 64 22 2c 22 74 79 70 65 22 3a 22 6c 6f 6e 67 22 7d 2c 7b 22 6e 61 6d 65 22 3a 22 76 61 6c 75 65 22 2c 22 74 79 70 65 22 3a 22 73 74 72 69 6e 67 22 7d 2c 7b 22 6e 61 6d 65 22 3a 22 74 69 6d 65 22 2c 22 74 79 70 65 22 3a 22 6c 6f 6e 67 22 7d 5d 7d 00 0c 64 69 4e 57 ee 5f 83 7d a0 a8 7f b7 bb 60 33 02 18 02 08 74 65 73 74 f4 cf b6 ce ee 49 0c 64 69 4e 57 ee 5f 83 7d a0 a8 7f b7 bb 60 33 (Obj...avro.schem a..{"type":"reco rd","name":"Prim itiveTestBean"," namespace":"test ","fields":[{"na me":"id","type": "long"},{"name": "value","type":" string"},{"name" :"time","type":" long"}]}..diNW._ .}.....`3....tes t.....I.diNW._.} .....`3) 枯れたプロジェクトとは言い難いためまだまだいくつかのバグが散見されるので、 使用には 注意が必要である。 4.7 Message Pack Message Pack は古橋貞之氏が作成したシリアライズライブラリで、Apache Lisence Version 2.0 にて公開されている。 特徴としては「性能を重視したシリアライズ形式」と謳われている通り、シリアライズ・デシリアライズの 9
  • 10. 速度が非常に優秀であることが挙げられる。また、Java を含む各種言語向けの操作用ライブラリが 提供されている。 シリアライズは以下のような形で実装する。 Packer pack = new Packer(out); if(schema == null){ pack.pack(obj); }else{ pack.packWithSchema(obj, schema); } スキーマ情報が存在しなくてもシリアライズ可能であるが、明示的にデータフォーマットを指定した い場合は独自書式のスキーマ定義を用意する必要がある。 たとえば配列を扱う場合は、以下のようにスキーマを定義する。 (array string) デシリアライズは以下のような形で実装する。 Unpacker unpk = null; if(bufferSize > 0){ unpk = new Unpacker(is, bufferSize); }else{ unpk = new Unpacker(is); } for(Object obj : unpk){ if(schema == null){ return (T)obj; }else{ return (T)schema.convert(obj); } } return null; 上記ソースでは一つのクラス前提の処理になっているが、Message Pack も Hadoop Avro と同様 に複数のクラスをまとめてシリアライズ・デシリアライズする事が可能になっている。 シリアライズデータは以下のようになる。以下は ASCII 文字を値としてもつ配列をシリアライズ化し たものである。JSON フォーマットのデータをバイナリ化したかのような、非常にシンプルな構成に なっていることが分かる。 dc 00 2f a1 30 a1 31 a1 32 a1 33 a1 34 a1 35 a1 36 a1 37 a1 38 a1 39 a1 3a a1 3b a1 3c a1 3d a1 3e a1 3f a1 40 a1 41 a1 42 a1 43 a1 44 a1 45 a1 46 a1 47 a1 48 a1 49 a1 4a a1 4b a1 4c a1 4d a1 4e a1 4f a1 50 a1 51 a1 52 a1 53 a1 54 a1 55 a1 56 a1 57 a1 58 a1 59 a1 5a a1 5b a1 5c a1 5d a1 5e (../.0.1.2.3.4.5. 6.7.8.9.:.;.<.=. 10
  • 11. >.?.@.A.B.C.D.E. F.G.H.I.J.K.L.M. N.O.P.Q.R.S.T.U. V.W.X.Y.Z.[.¥.]. ^) こちらも枯れたプロジェクトとは言い難いため、特に Java 版のシリアライズ・デシリアラ イズ実装にはバグが多数存在するため、使用には注意が必要である。 4.8 ここまでのまとめ 上述した各種手法についてまとめる。 データ形式 スキーマ定義 複数パッケージ データの Java 以 外での使用 Serializable バイナリ 不要 不可 不可 Deserializable バイナリ 不要 不可 不可 JSONIC テキスト(JSON) 必要(クラス) 不可 可 FlexJson テキスト(JSON) 指定も可 不可 可 Protocol バイナリ 必要(IDL) 不可 可 Buffers Hadoop Avro バイナリ 必要(JSON) 可 可 Message Pack バイナリ 指定も可(独自書 可 可 式) データ形式:シリアライズ後のデータ形式 スキーマ定義:シリアライズ・デシリアライズ時にスキーマ定義が必要かどうか 複数パッケージ:複数のクラスを一度にシリアライズ・デシリアライズする事ができるか データの Java 以外での使用:Java 以外でもシリアライズデータを扱うことができるか。 5 各種シリアライズ手法による性能評価 今まで述べてきたシリアライズ手法各種について、性能評価を実施した。 シリアライズ手法  Java 標準 API  Serializable  Externalizable  JSON 形式:JSONIC  JSON 形式:FlexJson  Hadoop Avro  Message Pack  Protocol Bufferes 対象データ  文字列(Hello World)  文字列(1MB) ※ランダム  数値(int)※ランダム  数値(long)※ランダム  数値(double)※ランダム  配列(1KB の文字列 256 要素)※ランダム  List(1KB の文字列 256 要素)※ランダム 11
  • 12. Map(Key:256Byte の文字列/Value:int 1024 の要素)※ランダム  クラス(Serializable 対応)  クラス(Externalizable 対応) 評価軸  シリアライズ速度( s)  デシリアライズ速度( s)  シリアライズ後のデータサイズ(byte) テスト手法  上記各手法を用いてデータのシリアライズ・デシリアライズをそれぞれ1万回くりかえし、 結果の平均値を算出した  ディスクの読み書き速度が測定に影響しないよう、シリアライズしたデータはメモリ内に格 納し、メモリ内のデータをさらにデシリアライズした。 テスト環境  CPU:Core2Quad(Intel(R) Xeon(R) CPU E5540 @ 2.53GHz)  Memory:4GB なお、シリアライズ手法によっては、特定のデータ形式が扱えないものも存在するため、それらにつ いては評価対象外としている。 (数値としては「0」扱いとしている。後述の詳細結果内では「-」表記としている) たとえば Java 標準 API については、「クラス(Externalizable 対応)」のみ Externalizable クラ スとして実装したものに対して評価し、それ以外は Serializable 対応クラスにて評価を行った。 JSONIC についてはシリアライズ後 JSON 記法に成り得ないデータ形式(単純な文字列や数値) についてはシリアライズができないため未評価である。 また、Protocol Buffers については実装が特殊なため、「クラス(Serializable 対応)」のみの評価 となる。 12
  • 13. 5.1 結果(シリアライズ) Java標準API 5.2 結果(デシリアライズ) Java標準API 13
  • 14. 5.3 結果(データサイズ) Java標準API 5.4 ここまでのまとめ 結論から言うと、Message Pack がシリアライズ速度、デシリアライズ速度、シリアライズ後のデータ サイズ、全てにおいて最も優秀である。 Java 標準 API や Avro では、数値や文字列を Java のオブジェクトとして扱っているため、今回の 条件ではシリアライズ速度やデータサイズで損をしている部分があると思われるが、それを割り引い ても Message Pack の優秀さが際立つ結果となった。 Protocol Buffers についてはクラスのシリアライズ・デシリアライズについてのみ評価を行ったが、 データサイズの小ささは群を抜いている。複雑な構造のクラスや、インスタンスが多くデータが肥大 するようなクラスの場合は強みを発揮すると思われる。 ただし本論では実装の汎用性や簡易性などを考慮して、Message Pack が一番使い勝手の良い シリアライズ手法と判断する。 なお、上記グラフでは詳細な結果がわかりづらいため、本論末に詳細結果一覧を記載する。興味 の有る方は参照されたい。 6 圧縮アルゴリズムについて 以上、各種シリアライズ形式について述べてきたが、データの省サイズ化という観点から考えるとシ リアライズデータのデータ構造の効率化だけでは物足りない部分もある。 そこで、シリアライズしたデータをさらに圧縮アルゴリズムにより圧縮化することで、どの程度の省サ イズ化が果たせるか、検証を行った。 とはいえただ圧縮率が高いだけで圧縮・伸長速度が遅いアルゴリズム(bzip21等)では用途が制限 されてしまうため、 ・ 圧縮率はほどほど ・ 圧縮・伸長速度が速い というアルゴリズムを中心に調査した。 1 http://www.bzip.org/ 14
  • 15. 今回は、一般的な圧縮アルゴリズムとして Deflate アルゴリズム、圧縮伸長速度が速いことで一部 注目を集めている QuickLZ アルゴリズムを評価対象として、性能比較を行った。 なお、以降はシリアライズ手法については Message Pack のみを対象として話を進める。 6.1 Deflate アルゴリズム Deflate1はフィル・カッツが開発した辞書式による圧縮アルゴリズムで、非常に多岐に渡って使用さ れている2。 Deflate では、辞書式圧縮方式として著名な LZ773と、頻出データに小さいデータを割り当てる圧 縮方式であるハフマン符号化4(動的ハフマン符号化)を組み合わせることで、高圧縮でかつ圧縮・ 伸長速度が比較的速いアルゴリズムを実現している。 また、圧縮レベル(1~9)を任意で設定できるため、圧縮率と圧縮・伸長速度のトレードオフを使用 者が調節できるようになっていることも特徴である。 6.2 QuickLZ アルゴリズム QuickLZ5は、GPL ライセンスで公開されているオープンソースライブラリである。圧縮・伸長速度 の速さにこだわったアルゴリズムで、他の同種のアルゴリズムに比べても速度が優秀だとされている (QuickLZ のサイトに掲載されているベンチマーク結果6では、他アルゴリズムよりも優秀である) QuizkLZ は、レベル指定(1~3)により圧縮速度と伸長速度のトレードオフを調節できるようになっ ている。レベル1だと圧縮速度優先(伸長速度はそれほど速くない)になり、レベル3だと伸長速度 優先となる。 7 圧縮アルゴリズムを用いたシリアライズの性能評価 Message Pack と各種圧縮アルゴリズムを用いて、シリアライズ・デシリアライズの性能評価を実施 した。 シリアライズ手法  Message Pack 圧縮手法  無圧縮  Deflate  圧縮・伸張速度優先(レベル1)  圧縮率優先(レベル9)  ハフマン符号化のみ  QuickLZ  圧縮速度優先(レベル1) 1 http://ja.wikipedia.org/wiki/Deflate 2 GZIP や ZIP などの圧縮形式や、HTTP 通信時の圧縮アルゴリズムとしても採用されている(GZIP 圧縮)。 Apache では圧縮用のモジュールとして mod_deflate が標準で搭載されている。また zlib というライブラリも用意 されており多くの Linux 系 OS には標準搭載されている。 3 http://ja.wikipedia.org/wiki/LZ77 4 http://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%95%E3%83%9E%E3%83%B3%E7%AC%A6%E5 %8F%B7 5 http://www.quicklz.com/ 6 http://www.quicklz.com/bench.html を参照のこと 15
  • 16. 伸長速度優先(レベル3) 対象データ  文字列(Hello World)  文字列(1MB) ※ランダム  数値(int)※ランダム  数値(long)※ランダム  数値(double)※ランダム  List(1KB の文字列 256 要素)※ランダム  Map(Key:256Byte の文字列/Value:int 1024 の要素)※ランダム 評価軸  シリアライズ速度( s)  デシリアライズ速度( s)  シリアライズ後のデータサイズ(byte) テスト手法  上記各手法を用いてデータのシリアライズ・デシリアライズをそれぞれ1万回くりかえし、 結果の平均値を算出した  ディスクの読み書き速度が測定に影響しないよう、シリアライズしたデータはメモリ内に格 納し、メモリ内のデータをさらにデシリアライズした。 テスト環境  CPU:Core2Quad(Intel(R) Xeon(R) CPU E5540 @ 2.53GHz)  Memory:4GB 7.1 結果(シリアライズ) 16
  • 17. 7.2 結果(デシリアライズ) 7.3 結果(データサイズ) 7.4 ここまでのまとめ QuickLZ による圧縮を試みたが、無圧縮時に比べてもデータサイズの増減がなく、圧縮が行えて なかった。QuickLZ では ASCII 文字の並びのデータについては圧縮が行われない傾向があり、 今回のような結果となっている。QuickLZ の圧縮率については次項で改めて評価する。 圧縮伸張の速度については、圧縮優先のレベル1の方が圧縮速度は速く、伸長優先のレベル3で は逆の結果が現れている。こちらについては想定通りの結果であった。 17
  • 18. Deflate アルゴリズムについては、レベル1とレベル9、ハフマン符号化の間で大きな差が確認でき なかった。こちらも今回使用したデータの特性も影響していると考えられる。 なお、単純な数値データなど、サイズが小さいデータについては圧縮を行うと逆にデータサイズが 肥大化するため、数値等のデータについては圧縮を行うのは適切では無い。 また無圧縮の時に比べてシリアライズ・デシリアライズにおおよそ 10 倍くらい時間がかかるため、圧 縮効果とのトレードオフで採用を検討する必要がある。 なお、上記グラフでは詳細な結果がわかりづらいため、本論末に詳細結果一覧を記載する。興味 の有る方は参照されたい。 8 実データへの応用 実際のデータに対してシリアライズ+圧縮アルゴリズムを適用して、どの程度のデータ圧縮が実現 できるか、調査した。 8.1 Twitter のクロールデータ 別件で定期的にクローリングしている Twitter のつぶやきデータを用いて検証を行った。 当該データは、Twitter の Streaming API(sample API)1から取得できるデータを定期的に獲得 し、MySQL に保存しているものである。 MySQL 上では擬似的に Key-Value Store のような形でデータを保存しており、Key は文字列 (varchar(255))、Value は JSON 形式の文字列(BLOB)として保存されている。 つぶやきデータは JSON 形式に変換された上で Value として保存されており、今回圧縮対象とし たのもこの JSON のデータになる。 8.1.1 データ圧縮 データ件数  約 180 万件(1,798,947 件) データサイズ  約 750MB(751,423,568byte MySQL の MYD ファイルのみのサイズ)  1レコードあたり平均長:417byte 圧縮対象  つぶやきデータ(JSON 形式)  JSON Map 形式に変換した上で、シリアライズ(+圧縮) シリアライズ形式  Message Pack 圧縮アルゴリズム  無圧縮  Deflate(ハフマン符号化)  QuickLZ(レベル1:圧縮速度優先) 検証方法  既存のデータを dump し、1レコードずつシリアライズ+圧縮処理を行った上で別のテー ブルに保存する。  既存のデータとシリアライズデータとのデータサイズ比較は、MySQL の MYD ファイルの サイズ比較にて実施。 結果は以下のようになった。 1 http://apiwiki.twitter.com/Streaming-API-Documentation 18
  • 19. データサイズ 元サイズ +Deflate +QuickLZ 元データを Message Pack 形式に変更することで、おおよそ 3/4 のサイズとなっている。 Message Pack+Deflate では、元のデータに比べて、おおよそ 2/3 のサイズとなっている。 JSON から Message Pack 形式に変更するだけでデータサイズをコンパクトにすることができるが、 さらにハフマン符号化などを行うことでデータの圧縮が可能であることが確認できた。 Message Pack をさらに QuickLZ で圧縮することでも更なる圧縮が行われたが、データの圧縮率 は非常に低かった(560.4MB 560.2MB)。Message Pack によりすでに効率的なデータ格納が 果たされているため、非冗長のデータに対する圧縮をスキップする傾向の強い QuickLZ での圧縮 はそれほど効果が無かったようである。 8.1.2 デシリアライズ速度 上記シリアライズデータがどの程度の速度で復元できたか、調査した。 データ件数  約 180 万件(1,798,947 件) データサイズ  無圧縮  約 560MB(560,456,384 byte MySQL の MYD ファイルのみのサイズ)  1レコードあたり平均超:311byte  Deflate  約 500MB(499,939,996 byte MySQL の MYD ファイルのみのサイズ)  1レコードあたり平均長:277byte  QuickLZ  約 578MB(560,261,688 byte MySQL の MYD ファイルのみのサイズ)  1レコードあたり平均長:311byte デシリアライズ形式  Message Pack 圧縮アルゴリズム  無圧縮  Deflate(ハフマン符号化)  QuickLZ(レベル1:圧縮速度優先) 検証方法  シリアライズデータを全件 dump し、1レコードずつ伸長処理+デシリアライズを行う。  1レコードあたりの復元速度の平均を測定。 結果としては以下のようになった。 デシリアライズ速度( s) deserialize dytes / micro sec Message Pack 25 s 12.44 byte/ s Message Pack+Deflate 31 s 8.93 byte/ s 19
  • 20. Message Pack+QuickLZ 19 s 16.36 byte/ s Message Pack 単体、Message Pack+Deflate、Message Pack+QuickLZ いずれも1レコード あたり数十 s でのデシリアライズが行えた。非常に高負荷・高トラフィックのシステムでは微妙な数 値かもしれないが、たいていのシステムであれば許容範囲の数値と思われる。 上記のように、既存のシリアライズ形式と圧縮アルゴリズムを組み合わせることで、現実的な処理時 間でデータの圧縮が行えることが確認できた。 また、Deflate に比べて QuickLZ は圧縮率が低いが伸長速度は速い、という、仕様として言われ ている通りの結果が確認できた。 適応する現場の要件に応じて採用するアルゴリズムを変える、というのが落とし所になると考えられ る。Deflate アルゴリズムの圧縮・伸長速度で十分なのであれば当該アルゴリズムにてデータ圧縮 率を稼ぎ、何よりも速度重視の場合は Message Pack 単体で用いるか、圧縮が行われやすいデー タ形式であれば QuickLZ を用いる、というケースが考えられる。 9 まとめと考察 Java の各種シリアライズ手法について調査した。調査の結果、Message Pack が他手法に比して 速度、データサイズの点で優秀であり、かつ実装も比較的容易であることが分かった。 データ圧縮手法について Deflate と QuickLZ を調査した。Deflate は QuickLZ に対して圧縮率 で優位であり、対して QuickLZ は圧縮・伸長速度で優位であることが確認できた。 応用として、Message Pack と Deflate、QuickLZ を組み合わせて Twitter のクロールデータの圧 縮を試みた。結果、それぞれ元データの 2/3~3/4 のサイズにデータが圧縮でき、伸長速度も数十 s で、多くのシステムの場に現実的に適用可能であることが分かった。 今回の調査によりデータシリアライズ+圧縮のメリットの多さ・デメリットの少なさについて十分な裏 付けが得られたため、実際にいくつかのシステムに本手法を適用することを考えている。結果として 今まで以上にマシンリソースの有効活用が果たされることを期待している。 10 参考文献・URL [1] オブジェクト直列化(Java) http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/serialization/index.html [2] JSONIC http://jsonic.sourceforge.jp/ [3] FlexJson http://flexjson.sourceforge.net/ [4] Protocol Buffers http://code.google.com/intl/ja/apis/protocolbuffers/docs/overview.html [5] Hadoop Avro http://hadoop.apache.org/avro/ [6] Message Pack http://sourceforge.jp/projects/msgpack/ [7] MessagePack for Java 作りかけリリース! - 古橋貞之の日記 http://d.hatena.ne.jp/viver/20100115/p1 [8] Protocol Bufferes は遅い - 古橋貞之の日記 http://d.hatena.ne.jp/viver/20081116/p1 [9] QuickLZ 20
  • 22. 11 [詳細]各種シリアライズ手法による性能評価 11.1 文字列(Hello World) Java標準API シリアライズ デシリアライズ Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 13 12 19 JSONIC - - - FlexJson 15 108 14 101 76 74 9 15 13 - - - 11.2 文字列(1MB) Java標準API シリアライズ デシリアライズ 22
  • 23. Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 8047 1048589 JSONIC - - - FlexJson 13611 20593 1048578 4281 2166 1048644 3235 720 1048581 - - - 11.3 数値(int) Java標準API シリアライズ デシリアライズ Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 55 81 JSONIC - - - 23
  • 24. FlexJson 15 98 9 89 65 62 5 17 5 - - - 11.4 数値(long) Java標準API シリアライズ デシリアライズ Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 55 82 JSONIC - - - FlexJson 17 122 19 95 68 68 5 17 9 - - - 24
  • 25. 11.5 数値(double) Java標準API シリアライズ デシリアライズ Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 53 84 JSONIC - - - FlexJson 20 125 18 99 73 69 5 17 9 - - - 11.6 配列(1KB の文字列 256 要素) Java標準API シリアライズ デシリアライズ 25
  • 26. Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 1107 1520 265260 JSONIC 16206 4751 265217 FlexJson 3409 4575 265217 1337 904 264283 - - - - - - 11.7 List(1KB の文字列 256 要素) Java標準API シリアライズ デシリアライズ Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 1236 1663 265274 26
  • 27. JSONIC 16016 4676 265217 FlexJson 3159 5190 265217 1355 933 264283 882 640 265219 - - - 11.8 Map(Key:256Byte の文字列/Value:int 1024 の要素) Java標準API シリアライズ デシリアライズ Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 1704 2354 275605 JSONIC 18224 5611 276463 FlexJson 1859 6505 276463 1249 1248 269334 1031 1480 270338 - - - 27
  • 28. 11.9 クラス(Serializable 対応) Java標準API シリアライズ デシリアライズ Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 24 47 116 JSONIC 52 79 43 FlexJson 38 154 92 108 130 224 - - - 25 13 19 11.10 クラス(Externalizable 対応) Java標準API シリアライズ デシリアライズ 28
  • 29. Java標準API データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) Java 標準 API 22 43 99 JSONIC 42 71 43 FlexJson - - - 109 133 238 - - - - - - 12 [詳細] 圧縮アルゴリズムを用いたシリアライズの性能評価 12.1 文字列(Hello World) シリアライズ デシリアライズ データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) 29
  • 30. 無圧縮 9 15 13 deflate(1) 82 965 21 deflate(9) 82 984 21 deflate(huffman) 83 1137 21 quicklz(1) 276 1125 26 quicklz(3) 255 972 26 12.2 文字列(1MB) シリアライズ デシリアライズ データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) 無圧縮 3235 720 1048581 deflate(1) 77276 2092 788583 deflate(9) 78841 2146 788583 deflate(huffman) 79523 2115 788583 quicklz(1) 28580 4384 1048590 quicklz(3) 79086 4099 1048590 30
  • 31. 12.3 数値(int) シリアライズ デシリアライズ データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) 無圧縮 5 17 5 deflate(1) 78 1052 13 deflate(9) 73 969 13 deflate(huffman) 74 961 13 quicklz(1) 265 1112 17 quicklz(3) 249 1000 18 12.4 数値(long) シリアライズ デシリアライズ 31
  • 32. データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) 無圧縮 5 17 9 deflate(1) 75 989 17 deflate(9) 75 976 17 deflate(huffman) 76 957 17 quicklz(1) 260 1098 22 quicklz(3) 248 980 22 12.5 数値(double) シリアライズ デシリアライズ データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) 無圧縮 5 17 9 deflate(1) 75 989 17 32
  • 33. deflate(9) 75 976 17 deflate(huffman) 76 957 17 quicklz(1) 260 1098 22 quicklz(3) 248 980 22 12.6 List(1KB の文字列 256 要素) シリアライズ デシリアライズ データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) 無圧縮 882 640 265219 deflate(1) 22358 7556 199361 deflate(9) 20893 7338 199362 deflate(huffman) 22305 7629 199362 quicklz(1) 7466 2233 265228 quicklz(3) 17957 2148 265228 33
  • 34. 12.7 Map(Key:256Byte の文字列/Value:int 1024 の要素) シリアライズ デシリアライズ データサイズ シリアライズ( s) デシリアライズ( s) データサイズ(byte) 無圧縮 1031 1480 270338 deflate(1) 22124 8172 207454 deflate(9) 22199 8108 207455 deflate(huffman) 23816 8657 207454 quicklz(1) 7845 3108 270347 quicklz(3) 18737 2918 270347 34