snuffkinの遊び場

IT関係、スポーツ、数学等に関することを、気が向いたときに書いてます。

JBoss Marshalling vs MessagePackでシリアライズサイズの勝負!

ちょっと興味があり、シリアライズフレームワークについて調べてみました。Java標準のシリアライズはサイズが大きくなってしまうため、いろんな人が工夫して小さくシリアライズする仕組みを考えています。そんな中で、今回は(今回しかやらないかもしれませんが)、JBoss MarshallingとMessagePackでどちらが小さなサイズにシリアライズできるのか測ってみました。

フレームワークの紹介

JBossの周辺で使われているシリアライズの仕組み。Javaシリアライズでは効率が悪いため、独自に開発されました。

言語に依存しないシリアライズの仕組み。Format specificationを読むと、シリアライズの小さくするための工夫が徹底している感じがします。

シリアライズ対象のデータ

次のような、どこにでもありそうなクラスを作ってみました。

package jp.gr.java_conf.snuffkin.sandbox.infinispan;

import java.io.Serializable;

import org.msgpack.annotation.Message;

@Message
public class Tweet implements Serializable{
    private static final long serialVersionUID = -7144860256641395394L;
    private String userid;
    private long timestamp;
    private String message;
    
    public String getUserid() {
        return userid;
    }
    public void setUserid(String userid) {
        this.userid = userid;
    }
    public long getTimestamp() {
        return timestamp;
    }
    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public String toString() {
        return "Tweet [userid=" + userid + ", timestamp=" + timestamp
                + ", message=" + message + "]";
    }
    
}

コメントは書いていませんが、簡単なクラスなのでご勘弁ください。要は、以下のようなプロパティを持つクラスです。

String userid
long timestamp
String message

各プロパティには、以下のような値を設定します。

userid="snuffkin"
timestamp=現在時刻をミリ秒単位で表現した値
message=140文字のASCII文字列

シリアライズの結果

JBoss Marshalling、MessagePackをシリアライズし、ネットワークに流した結果をWiresharkで解析してみました。その結果は、次の通りです。

JBoss Marshalling

269byteのサイズにシリアライズされました。

クラス名やプロパティ名がシリアライズされたデータに入っているので、パッケージ名が長かったりするとデータが大きくなりますね。固い仕組みなのかもしれませんが、サイズだけ見るとロスがあります。手元に仕様書がないのですが、「3e」でプロパティを区切って、次にデータ長・データと並んでいるように見えます。

MessagePack

162byteのサイズにシリアライズされました。

うおっ。見るからにこちらの方が小さいです。MessagePackはサイズが小さなデータについては、型とデータ長を合わせて1byteに収めるようになっているせいか、見るからに隙間が少ないですね。また、プロパティは定義した順に配列として表現されており、プロパティ名の情報は失われています。

という訳で、結果はMessagePackの勝ち! 約40%もの差をつけての圧勝ですね。シリアライズに特性があったり(この仕組みだと、小さなデータほどサイズ比が大きくなりますね)、実際に使用するときにはサイズだけでなくシリアライズ速度も重要だったり、観点はいろいろあるべきだと思うのですが、ここでは、そのあたりは考慮に入れていません。サイズを比較したのみですので、あくまでも、ひとつの側面としてご参考ください。