DenkiYagi RSSフィード

2010-10-31

[][]Jackson vs JSONIC、結果はJacksonの圧勝

2010/11/10追記 JSONIC 1.2.5 ベータ2で劇的に高速化されたとのことです。すばらしい!2010-11-10 - A.R.N [日記]

というつぶやきをしたところ、

とツッコミを受けたので訂正をします。APIレベルの話ではなくて内部処理レベルの話をしていたんですが、変なことを言って誤解を招いてスイマセン。言いたかった趣旨としては、単にJSONICだとシリアライズ対象のデータが巨大になった場合のパフォーマンスが非常に悪いという話です。

ということで、最近弊社で使い始めたJacksonとのベンチマークを掲載。

比較対象

ベンチマークコード

  • HashMap<String, ArrayList<String>>をシリアライズしてFileOutputStreamに吐くだけのプログラムです。
  • JSON.encode()、ObjectMapper.writeValue()の部分にしか違いはありません。
JSONIC
    public static void main(String[] args) throws IOException {
        HashMap<String, Object> map = new HashMap<String, Object>();
        for (int i = 0; i < 1000; i++) {
            List<String> list = new ArrayList<String>();
            for (int j = 0; j < 1000; j++) {
                list.add("item" + j);
            }
            map.put("key" + i, list);
        }

        long t1 = System.nanoTime();
        FileOutputStream stream = new FileOutputStream("temp.txt");

        // - - - - - - - - - - - - - -
        JSON.encode(map, stream);
        // - - - - - - - - - - - - - -

        System.out.println(System.nanoTime() - t1);
    }
Jackson
    public static void main(String[] args) throws IOException {
        HashMap<String, Object> map = new HashMap<String, Object>();
        for (int i = 0; i < 1000; i++) {
            List<String> list = new ArrayList<String>();
            for (int j = 0; j < 1000; j++) {
                list.add("item" + j);
            }
            map.put("key" + i, list);
        }

        long t1 = System.nanoTime();
        FileOutputStream stream = new FileOutputStream("temp.txt");

        // - - - - - - - - - - - - - -
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(stream, map);
        // - - - - - - - - - - - - - -

        System.out.println(System.nanoTime() - t1);
    }

結果

Jacksonの方が10倍以上速いです。Map1000×List1000とかJSONでやるなって話もなくはないんですが、弊社ではクライアント側で大量データ扱ってナンボみたいなところがあるので、結構重要だったりします。

JacksonJSONIC速度比
Map1000×List1000299.063 2455527.890 9321:18.4840198
Map1000×List100001348.112 46699898.403 2521:74.1024253
Map10000×List10001251.504 34149485.444 9341:39.5407697

単位はミリ秒、ナノ秒まで表記。

追記

型をつくってシリアライズしたときどうなるんだろーと思って、こんなのもテストしてみました。

    public static void main(String[] args) throws IOException {
//        HashMap<String, Person> data = new HashMap<String, Person>();
//        for (int i = 0; i < 100000; i++) {
//            data.put("item" + i, new Person("id"+i, "name"+i, i));
//        }

        ArrayList<Person> data = new ArrayList<Person>();
        for (int i = 0; i < 10000; i++) {
            data.add(new Person("id"+i, "name"+i, i));
        }

        long t1 = System.nanoTime();

        FileOutputStream stream = new FileOutputStream("temp.txt");
//        ObjectMapper mapper = new ObjectMapper();
//        mapper.writeValue(stream, data);
        JSON.encode(data, stream);

        System.out.println(System.nanoTime() - t1);
    }

    private static class Person {
        private String id;
        private String name;
        private int age;

        public Person(String id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }

        public int getAge() {
            return age;
        }

        public String getId() {
            return id;
        }

        public String getName() {
            return name;
        }
    }

JacksonJSONIC速度比
Map100238.047 49060.364 6341:0.253582317
Map1K264.846 439188.372 4451:0.711251568
Map10K380.608 350979.267 1741:2.57289987
Map100K465.197 5165526.531 8641:11.8799686
List100229.535 63459.121 7871:0.25757128
List1K260.241 303188.218 8311:0.723247343
List10K364.508 523974.164 1671:2.67254153
List100K477.555 9675320.503 2841:11.1411094

Jacksonは要素数が増えても異常なほど遅くならない感じですね。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証