jsoncpp和rapidjson哪個好用?
身為 RapidJSON 作者,剛剛做完 28 個 C/C++ JSON 庫(包括題目中的兩個)的評測 miloyip/nativejson-benchmark,回來回答這個問題。
標準符合程度(越高越好):
JsonCpp 得88分,算是比較好的了。如果仔細看每個部分(https://rawgit.com/miloyip/nativejson-benchmark/master/sample/conformance.html),就是JSON正確性和roundtrip上有幾個問題。而RapidJSON在JSON正確性、string和roundtrip上都是滿分,開啟了 full precision 選項的話,解析double也是滿分。
解析和生成JSON的耗時(越低越好):
可見RapidJSON比JsonCpp在解析上快了一個數量級,而生成上也近一個數量級了。解析至DOM後的內存用量(越低越好):
其他方面,例如功能、文檔、友好性等,就不在此逐一對比了。
RapidJSON也有一些缺點,例如有些API的設計比較奇怪,可能較難使用。我們會嘗試加入一些功能,使不太注重性能的部分能更容易使用。
如果讀者仍然想使用 JsonCpp,也可以參考這個評測,幫助改進它。這也是我做此評測的初衷,在開源代碼中互相學習,持續改進。沒人回答,我來回答一下吧,之前都用jsoncpp,自從發現rapidjson後,一直讓團隊用這個
易用性:rapidjson是全頭文件包含的,jsoncpp需要你內置編譯或編譯成庫;但rapidjson的一些介面不全,只提供了一層一層的這種解析方式,不能將某一層一次讀出來,實際用的時候,要簡單封裝一下,不然代碼量會很大;
性能:rapidjson的性能是現在所有的c++ json解析庫裡面最高的,沒有之一;容錯性:rapidjson只支持標準的 json 格式,很多人以為這個是缺點,我覺得這個是優點,大家都按照標準做,這是成本最低的;rapidjson之前是託管在Googe Code上的,現在已遷移到GitHub,地址:miloyip/rapidjson · GitHub
另外具體的性能測試,可以參考這個地址:mloskot/json_benchmark · GitHub
這是對流行C++ Json庫的一個總結:【總結】各種 JSON 解析庫的功能簡介-----------------------------------
2015-03-30Irons Du 推薦的nlohmann/json · GitHub,今天中午吃完飯,瞄了一下,發現這個庫比較符合我的審美,我喜歡一些小的東西,就做了一下簡易的測試1,現在工作用的機器是Windows,本來想用VS2013隨便編譯下,最後發現不行,主要問題是:
1). 對內部類重定義為同名類,VS不支持這樣,其實我也覺得怪怪的,至少我不會這樣寫;2). no_except關鍵字不認識3). enable_if的邏輯處理,現在VS 2013不支持前兩個倒好改,第三個就的確不想去改了,不過聽說VS2015-PRE能支持編譯2,最後用MingGW(G++ 4.91)編譯了一下,使用-O2優化,跑了下測試如下:
nlohmannjson.small: 1000 iterations of 500 parsings in 4.6015 to 4.62655 sec based on 2 benchmarksnlohmannjson.large: 1000 iterations of 1 parsings in 167.245 to 167.471 sec based on 2 benchmarks順便在同一個機器上跑了一下rapidjson的測試rapidjson.small: 1000 iterations of 500 parsings in 0.953772 to 0.954968 sec based on 2 benchmarksrapidjson.large: 1000 iterations of 1 parsings in 14.1077 to 14.1594 sec based on 2 benchmarks對照之前mloskot/json_benchmark · GitHub的測試數據,這個庫的性能還是不錯的,只是比起rapidjson還有不小差距
總結:
優點: 這個庫使用了大量的C++ 11標準元素,另外庫的設計上,也符合STL的一些標準,可配置性比較強;單文件方式,引用也比較方便;使用上,也有其獨到的地方,更接近JSON的本質;此外性能上還是不錯的,只是比rapidjson差,比libjson,jsoncpp之流還是強了不少缺點: 不支持VS2013,並且看作者的意思,他也不會去兼容VS2013,但作為一個Win7統治桌面操作系統的時代,VS2013一定會是一個主流的編譯器,這一點說不過去;代碼上,Morden C++的大量使用,對於一般的程序員來說,太不友好了;性能,好吧,他的確比rapidjson慢了5~10倍。結論:
玩票可以,實際項目還是用rapidjson吧一開始被rapidjson的介紹感動了,用了之後發現有內存泄漏。在路上,等有空上代碼。
rapidjson介面設計的不好,不好用,雖然只需要包含頭文件,另外主要也是用了其他內建json類型的語言給慣壞了,jsoncpp要編譯成庫就更加不方便了。最近工作需要用json,github上找了下,這個nlohmann/json好,只需要一個hpp文件,介面設計的比較易用,整體評價也不錯,Linux下面gcc要4.9
如果只是問「好用」的話,我更傾向於選擇jsoncpp。介面設計的精巧簡練又易用,如果有需要,源碼也能半天內看完,實現讓人感覺很優美。而且是json官方推薦的解析工具。缺點就在於大量使用STL,相較而言解析效率一般般。
rapidjson時空效率確實表現出色,上面作者都親自站台了,我等渣渣也不好說什麼。只是怎麼說,介面和實現並不那麼接地氣,不客氣地說簡直是亂七八糟。因為我們之前穩定跑的是jsoncpp,所以考量之後還是放棄了
綜上,如果系統的瓶頸確定是在json解析上,那不妨試試rapidjson;如果只是為了避免這點性能損失,不建議rapidjson
不好使,整的都是些啥亂七八糟的介面啊,json轉string還亂碼了,棄之,煩人。
rapidjson太難用了,介面設計的很奇怪,不建議使用。
我測試了單線程和多線程下rapidjson和jsoncpp的效率測試硬體環境: Windows Server 2008 x64 intel E5-2620(2處理器,單顆cpu12核超線程) 16G內存同樣條件下測試結果如下: | 平均每秒解析次數 線程數 | rapidjson | jsoncpp 1 | 329029 | 67993
2 | 381968 | 78100
4 | 203786 | 147608 8 | 152234 | 270810 12 | 124466 | 400020 16 | 51355 | 409102 24 | 52359 | 502005rapidjson隨著線程數越大,單核利用率和總cpu利用率都呈下降趨勢,jsoncpp可以完全利用單核,並在24線程時總cpu利用率達到100%。測試樣本如下:{"NO":"京A12345","area1":"A","area2":0,"color":2,"data_type":4610,"gnsscenterid":50303,"gps":{"alarm":0,"altitude":114,"cmb_date":"2015-01-01 14:18:10","direction":194,"excrypt":0,"lat":"22.716590","lon":"138.608925","state":0,"time":"2015-06-11 14:18:07","vec1":26,"vec2":26,"vec3":34794},"type":0}//以下是測試代碼中的主要部分,其中命名空間「rapidjson」中封裝了rapidjson的部分操作。
namespace rapidjson
{
static void parse(rapidjson::Document document, const char* msg)
{
if (document.Parse&<0&>(msg).HasParseError())
{
throw document.GetParseError();
}
}
static void parse(rapidjson::Document document, const std::string msg)
{
rapidjson::parse(document, msg.c_str());
}
}
void test_thread(int test_type)
{
if (test_type == TEST_RAPIDJSON)
{
while (is_running_)
{
rapidjson::Document root;
rapidjson::parse(root, content);
num_ ++;
}
}
else if (test_type == TEST_JSONCPP)
{
while (is_running_)
{
Json::Value root;
Json::Reader reader;
reader.parse(content, root);
num_ ++;
}
}
}
void start_test()
{
is_running_ = true;
for (int i=0; i&
t-&>join();
}
thread_s_.clear();
}
void on_timer()
{
output(num_);
num_ = 0;
}
只用過jsoncpp.這貨用起來很簡單.只是有個地方我不大明白,就是在本地序列化成json的時候,默認生成的是[{"key":"xxx"}]
這個樣子,而不是{"key":"xxx"}.注意後面還有個換行。而jsoncpp本身的格式檢測很嚴格,不是標準的json格式是解析不出來的, 所以外面加了個[ ]生成的json由jsoncpp的Reader類和Value類不能直接解析,還得做下字元串處理。有點不能理解為什麼要這麼做,如果有知道為什麼的人請告訴我一下。不過最近github上jsoncpp的更新蠻勤快的,不知道這個地方改了沒有,沒仔細看。以後有機會試試rapidjson
我對RapidJSON的解析能力沒有任何疑問,雖然沒真正實測過,不過測試過RapidXML解析速度,比tiny之流快了一個數量級。其解析寫法也還湊合,沒什麼吐槽的但還是要說以下一件事開發一個跨平台的特效編輯器,用RapidJSON導出json文件(cocos集成這個庫,就直接拿來用),導出json文件死活有亂碼(/u000000),還有字元丟失的情況,也不知道是不是writer是不是有問題,折騰幾小時後,去git下來jsoncpp,集成項目很麻煩,棄之,然後果斷換成libjson,分分鐘問題解決了。
因為有一些特殊的需求, 於是自己寫了個json的解析(只做了DOM,通過了JSON_checker的36個測試,
全部解析不超過300行, 用scanf處理的double)
在MAC系統Processor: intel i5 3.2GHz, Memory: 8GB 1867MHz DDR3Compiler: Apple Clang 8.0 (編譯參數-O2)上測試了twitter.json的解析,在解析DOM和輸出文本這兩方面,都只佔用了rapidjson一半的時間。nmsccjson use: 0.001614
nmsccjson use: 0.001219
nmsccjson use: 0.001189
nmsccjson use: 0.001189
nmsccjson use: 0.001183
rapidjson use: 0.004272
rapidjson use: 0.002522
rapidjson use: 0.002235
rapidjson use: 0.002527
rapidjson use: 0.002473
nmsccjson dump: 0.036483
rapidjson dump: 0.060545
以下是測試代碼
#include &
#include &
#include &
#include &
#include &
#include &
#include &
using namespace nms;
int main(int argc, char *argv[]) {
File twitter("twitter.json", File::Read);
const auto size = twitter.size();
auto str = new char[size+1];
twitter.read(str, size);
str[size] = " ";
double nmsccjson_dump = 0;
double rapidjson_dump = 0;
// nmscc
{
Timer t;
JDoc json(str, size);
writef("twitter = {}
", json.value());
nmsccjson_dump = t.duration();
}
// rapidjson
{
Timer t;
rapidjson::Document doc;
doc.Parse(str);
rapidjson::OStreamWrapper osw(std::cout);
rapidjson::Writer&
doc.Accept(writer);
rapidjson_dump = t.duration();
}
printf("-------------------
");
// nmscc
for (int i = 0; i &< 5; ++i) {
Timer t;
JDoc json(str, size);
printf("nmsccjson use: %f
", t.duration());
}
// rapidjson
for(int i = 0; i &< 5; ++i) {
Timer t;
rapidjson::Document doc;
doc.Parse(str);
printf("rapidjson use: %f
", t.duration());
}
printf("nmsccjson dump: %f
", nmsccjson_dump);
printf("rapidjson dump: %f
", rapidjson_dump);
return 0;
}
rapidjson在編譯開啟優化的時候,會有內存溢出的問題。(親測)
https://github.com/nlohmann/json
期待添加 https://developer.gnome.org/json-glib/ 和 http://doc.qt.io/qt-5/json.html benchmark 可能 GNOME、KDE沒有重json需求
贊下rapidjson,性能不錯,介面不符合自己的習慣可以再次封裝下!
rap解析速度快很多
之前只是玩玩,並沒有深入到速度性能的層次,單從新手配置的角度來說,rapidjson我花了幾分鐘,jsoncpp用了幾天,還沒配好。。當然也有可能是我用了mfc的緣故。。。
jsoncpp is easy to use in ubuntu, generate a header file and just use, thats it.
not program in Windows many years...贊同,都是裝逼貨。就一個簡單的字元串-&>json,整這麼多亂七八糟的介面,還綁定到事件了,吃飽了撐的?
c++er有這個需求的99%的也就是想將字元串格式轉換為便於操作的數組/鏈表而已。你就提供一個load/save和 添加刪除成員項的函數不就是了,搞那麼多亂七八糟的介面幹嘛,模板/分配器都來了,你是要上天么?
rxxxJSON 還建立了一個網站來宣傳。。。服了,有點噁心。還定義那麼多頭文件,莫名其妙的各種介面函數。
現在是互聯網時代,程序員找一個工具使用,目的是為了滿足業務需要的功能,而不是為了搞技術深度研究的。
推薦閱讀: