Jackson vs JSONIC、結果はJacksonの圧勝
2010/11/10追記 JSONIC 1.2.5 ベータ2で劇的に高速化されたとのことです。すばらしい!2010-11-10 - A.R.N [日記]
というつぶやきをしたところ、
@terurou @gabu JSONICでもWriterにもOutputStremにも出力できますよ?
2010-10-31 19:12:30 via web to @terurou
とツッコミを受けたので訂正をします。APIレベルの話ではなくて内部処理レベルの話をしていたんですが、変なことを言って誤解を招いてスイマセン。言いたかった趣旨としては、単にJSONICだとシリアライズ対象のデータが巨大になった場合のパフォーマンスが非常に悪いという話です。
ということで、最近弊社で使い始めたJacksonとのベンチマークを掲載。
比較対象
- JSONIC 1.2.4
- Jackson 1.6.1
ベンチマークコード
- HashMap
>をシリアライズして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でやるなって話もなくはないんですが、弊社ではクライアント側で大量データ扱ってナンボみたいなところがあるので、結構重要だったりします。
Jackson | JSONIC | 速度比 | |
---|---|---|---|
Map1000×List1000 | 299.063 245 | 5527.890 932 | 1:18.4840198 |
Map1000×List10000 | 1348.112 466 | 99898.403 252 | 1:74.1024253 |
Map10000×List1000 | 1251.504 341 | 49485.444 934 | 1: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; } }
Jackson | JSONIC | 速度比 | |
---|---|---|---|
Map100 | 238.047 490 | 60.364 634 | 1:0.253582317 |
Map1K | 264.846 439 | 188.372 445 | 1:0.711251568 |
Map10K | 380.608 350 | 979.267 174 | 1:2.57289987 |
Map100K | 465.197 516 | 5526.531 864 | 1:11.8799686 |
List100 | 229.535 634 | 59.121 787 | 1:0.25757128 |
List1K | 260.241 303 | 188.218 831 | 1:0.723247343 |
List10K | 364.508 523 | 974.164 167 | 1:2.67254153 |
List100K | 477.555 967 | 5320.503 284 | 1:11.1411094 |
Jacksonは要素数が増えても異常なほど遅くならない感じですね。