JSON/BSON/MessagePack速度・サイズ検証(2)

JSON/BSON/MessagePack 処理速度・データサイズ完全比較 - なぜか数学者にはワイン好きが多い

これじゃ説明が足りないなーと思ったので.

ベンチマークは,単純にC++で僅かなHashとデータとしてわりと長く続く配列をシリアライズ後,値を検証しつつデシリアライズする単純なものです.

どんなデータを使ったかを具体的に書きます.
設計上は,こんなデータ構造を想定.

[
 {"key":"0000000000"},
 {"v":1, "t":1234567, "n":30},
 {"val":[
          [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1234567],
          [0, 1, ..., 1234567],
           ... ,
          [0, 1, ..., 1234567]
        ]
 } 
]

配列の要素が3つから成り,最初はキー,次がヘッダ,最期がバリューです.
この(JSON/BSON/MessagePack 処理速度・データサイズ完全比較 - なぜか数学者にはワイン好きが多いC++のプログラムを実行すると,json-c.obj, bson.obj, msgpack.objの3つのファイルができます.

それらをダンプするrubyスクリプトが以下です.

JSONをダンプするプログラム.

#!/usr/local/bin/ruby19
require "json"

while gets()
  line = $_.chomp();
  jsonobj = JSON.parse(line);
  key = jsonobj[0]["key"];
  v = jsonobj[1]["v"];
  t = jsonobj[1]["t"];
  n = jsonobj[1]["n"];
  valarr = jsonobj[2]["val"];
  puts "key: #{key}";
  puts "header: version=#{v}, timestamp=#{t}, number=#{n}";
  valarr.each_index{|i|
    print "  #{i}: "
    (0..9).each{|j|
      print "#{j}:#{valarr[i][j]} ";
    }
    puts "timestamp=#{valarr[i][10]}";
  }
end;

ダンプ結果です.

 ./dump_json.rb < json-c.obj | head -32
key: 0000000000
header: version=1, timestamp=1352038522, number=30
  0: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  1: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  2: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  3: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  4: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  5: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  6: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  7: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  8: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  9: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  10: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  11: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  12: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  13: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  14: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  15: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  16: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  17: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  18: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  19: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  20: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  21: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  22: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  23: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  24: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  25: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  26: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  27: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  28: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522
  29: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038522


BSONをダンプするプログラム.

#!/usr/local/bin/ruby19
require "bson"

while bsonobj = BSON.read_bson_document(STDIN)
  key = bsonobj["0"]["key"];
  v = bsonobj["1"]["v"];
  t = bsonobj["1"]["t"];
  n = bsonobj["1"]["n"];
  valarr = bsonobj["2"]["val"];
  puts "key: #{key}";
  puts "header: version=#{v}, timestamp=#{t}, number=#{n}";
  valarr.each_index{|i|
    print "  #{i}: "
    (0..9).each{|j|
      print "#{j}:#{valarr[i][j]} ";
    }
    puts "timestamp=#{valarr[i][10]}";
  }
end;

ダンプ結果です.

./dump_bson.rb < bson.obj | head -32
key: 0000000000
header: version=1, timestamp=1352038523, number=30
  0: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  1: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  2: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  3: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  4: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  5: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  6: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  7: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  8: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  9: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  10: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  11: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  12: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  13: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  14: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  15: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  16: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  17: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  18: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  19: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  20: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  21: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  22: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  23: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  24: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  25: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  26: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  27: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  28: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523
  29: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038523


MessagePackをダンプするプログラム.

#!/usr/local/bin/ruby19
require "msgpack"

msgpackobj = MessagePack::Unpacker.new(STDIN);

msgpackobj.each{|mpobj|
  key = mpobj[0]["key"];
  v = mpobj[1]["v"];
  t = mpobj[1]["t"];
  n = mpobj[1]["n"];
  valarr = mpobj[2]["val"];
  puts "key: #{key}";
  puts "header: version=#{v}, timestamp=#{t}, number=#{n}";
  valarr.each_index{|i|
    print "  #{i}: "
    (0..9).each{|j|
      print "#{j}:#{valarr[i][j]} ";
    }
    puts "timestamp=#{valarr[i][10]}";
  }
};

ダンプ結果です.

./dump_msgpack.rb < msgpack.obj | head -32
key: 0000000000
header: version=1, timestamp=1352038524, number=30
  0: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  1: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  2: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  3: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  4: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  5: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  6: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  7: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  8: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  9: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  10: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  11: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  12: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  13: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  14: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  15: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  16: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  17: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  18: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  19: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  20: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  21: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  22: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  23: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  24: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  25: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  26: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  27: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  28: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524
  29: 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 timestamp=1352038524

Rubyの生産性の高さは凄いですね.
この3種のダンププログラムは,ほとんど差分が無いので,合計で5分くらいで作れてしまいました.
Perlの存在意義って,なんなんでしょうね?