なんびとたりとも俺の前は走らせねぇガチバトルです。
rapidjson - A fast JSON parser/generator for C++ with both SAX/DOM style API - Google Project Hostingfastest をうたうとは度胸があるなーと思いながら、半信半疑で試してみました。
Rapidjson is an attempt to create the fastest JSON parser and generator. Small but complete. Support...
https://code.google.com/p/rapidjson/
rapidjson も picojson 同様に、ヘッダファイルだけあればコンパイル出来る C++ 向け JSON パーサ(およびシリアライザ)です。
まずは rapidjson を使ったコード。
#include <rapidjson/document.h>
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#include <time.h>
int
main(int argc, char* argv[]) {
clock_t t;
t = clock();
for (int n = 0; n < 1000; n++) {
std::stringstream ss;
std::ifstream f;
f.open("foo.json", std::ios::binary);
ss << f.rdbuf();
f.close();
rapidjson::Document doc;
if (doc.Parse<0>(ss.str().c_str()).HasParseError()) {
std::cerr << "parse error" << std::endl;
return 1;
}
rapidjson::Value& entries = doc["entries"];
int i, l = entries.Size();
for (i = 0; i < l; i++) {
std::cerr << entries[rapidjson::SizeType(i)]["title"].GetString() << std::endl;
}
}
std::cout << "score: " << clock() - t << std::endl;
return 0;
}
そして picojson を使ったコード
#include <picojson.h>
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <time.h>
int
main(int argc, char* argv[]) {
clock_t t;
t = clock();
for (int n = 0; n < 1000; n++) {
std::stringstream ss;
std::ifstream f;
f.open("foo.json", std::ios::binary);
ss << f.rdbuf();
f.close();
picojson::value v; ss >> v;
picojson::array a = v.get<picojson::object>()["entries"].get<picojson::array>();
int i, l = a.size();
for (i = 0; i < l; i++) {
std::cerr << a[i].get<picojson::object>()["title"].to_str() << std::endl;
}
}
std::cout << "score: " << clock() - t << std::endl;
return 0;
}
picojson については、std::for_each を使っても見たけど結局自前ループで回した方が速い結果になりました。コンパイルは両者とも
g++ -std=c++11 -O2 foo.cxx
でやりました。読み込んでる JSON はこれを使いました。ウチのサイトの JSON 形式のフィードです。やってる内容は
- ファイルを読み込む
- パースする
- entries の一覧を取る
- 各 title の内容を標準エラーに出力する
結果は以下の通り。
rapidjson score: 3559
picojson score: 7961
こうなりました。picojson と比べて rapidjson がほぼ2倍速いという結果になりました。速い理由をソースを見ながら調べてみましたが、rapidjson は STL を使わず、自前で DOM ライクな API を提供しています。また std::string なども使いません。これによってオーバーヘッドを最小限に抑えているのだと思います。もちろん、picojson の STL フレンドリも僕は好きですし、他の C++ ライブラリと連携する際にも便利です。
Performance - rapidjson - Compares some performance benchmark results of rapidjson 0.1 and other parsers. Also gives some analysis. - A fast JSON parser/generator for C++ with both SAX/DOM style API - Google Project Hostingそれどころか、このスコア表を見ると picojson のスコアは素晴らしいレベルだと分かりました。
Why rapidjson is fast? rapidjson has made use of several techniques to achieve high performance. C++...
https://code.google.com/p/rapidjson/wiki/Performance
唯一難点として rapidjson は確かに速いのですが、パースエラー詳細に取る方法が分かりませんでした。(あるのかもしれません。知ってる人いたら教えて下さい)
という事で、これからも picojson 使って行こうと思います。