C++でnlohmann/jsonを使い、1万近くの配列をJSONファイルから読み込んでいます。
各配列の要素数は15前後です。
以下のC++コードの
reading >> j
という部分に16秒ほど処理時間がかかり、困っています。
C++
1#include <vector> 2#include <fstream> 3#include <nlohmann/json.hpp> 4 5using json = nlohmann::json; 6 7int main() { 8 const std::string path = "a.json"; 9 std::fstream reading(path.c_str()); 10 json j; 11 reading >> j; 12 13 std::vector<std::string> abc = j["ABC"]; 14 std::cout << abc[1] << std::endl;
使うライブラリがnlohmann/jsonでは無くても良いので、reading >> jに該当する処理がどうすれば速くなるかをご教示下さい。
余談ですが、pythonだと一瞬で似た操作が済むので、同様の速さがc++に出ることを期待していました。python使えや、と思うかもしれませんが、jsonを読み込んだ後の計算処理がc++の方が圧倒的に速いので、このような問題に直面しています。
蛇足かもしれませんが、c++の
reading >> j;
という処理はpythonだと以下のコードになります。
python3
1import json 2 3f = open("a.json" , "r") 4fl = json.load(f)
ベンチマーク見つけました。
https://github.com/miloyip/nativejson-benchmark
ファイルの読み込みがネックになってませんか?とりあえずfstreamのバッファを増やして処理時間が変化するか状況確認を
私自身は使ったことがないですが、速度的にはRapidJSON(https://github.com/Tencent/rapidjson)が速いという話を聞きます。こちらを使用されてみてはどうでしょうか。
一度全ての行について実行時間を計測したのですが、
const std::string path = "a.json";
std::fstream reading(path.c_str());
の部分(=ファイル読み込み)については数十msで処理が終わっていました。
あきらかに、
reading>>jの前後(上下?)を計測した時のみ16000ms〜17000msかかります。
RapidJSONについては、一度試したのですが、jsonファイルに格納されている配列を、変数に代入できない(そちらも同時に原因を探しています。マルチポストはしてません)ので、nlohmanm/jsonを、使っているという状況になります。
std::fstream reading(path.c_str());
はreadingストリームにパス設定しているだけなので、読み込んでいません。
reading >> j;
が読み込み&パースです。
また、シンプルにC++のfstreamが遅いので、ファイルI/O速度が重要なら使わない方が良いです。
(他の方法と比べて、群を抜いて遅いレベル)
初心者なもので、代わりにどう言ったものを使うことを推奨されますか?
私の場合、C++上でなんとかする時は、C言語のfopen系を使います。
(「fstream 遅い」等でググってもらえれば一般論は出てきます)
ですが、nlohmann/jsonで使えるかは分からないです。
また、pythonが問題ないとの事だったので、ファイルI/O速度に触れましたが、
どこが遅いかは確認していただいた方がよいかと思います。
ファイルサイズがそれほどでもないなら、パースが遅いはずなので。
ちなみに、プログラムは最適化で構築して計測していますよね?
すみません、初心者なものでしてVS2019を使っているのですがいつも実行時は「デバッグ無しで実行」を選択しているだけで、最適の掛け方もわかりません。
fopenは試してみます。
fileサイズは18441KBです
(たぶん)18Mくらいならfstreamでも問題ないかな?と思います。
>最適化
この辺りが分からないようであれば、速度を気にする前にVS基礎学習したほうが良いと思います。
※意味がある状態で計測できていない可能性があります。
とりあえず、上部ツールバーのソリューション構成が「Debug」なら
「Release」に変更してみて計測すると変化ありますか?
7800〜8500msに高速化しました?!
プロパティの最適化オプションについて初めて理解しました。
ありがとうございます????♂️
それでもやはり、読み込みに8秒はかかり過ぎ感が否めません…
最適化でパース部分が適正速度になったのだと思います。
ヘッダベースのライブラリと書いてあったので、コンパイル設定にかなり左右されると思われます。
こちらでは最適な設定かは分かりませんので、この辺りは学習願います。
残りのfstream速度に関してはtmpさんが指摘されているように、
バッファサイズを変更して改善があるかを確認されてみてはいかがでしょう。
(fstream バッファサイズ等でググってみてください)
それでも遅いようならfopenなりにチャレンジするとよいかと。
fopenは試しましたが、現在使用しているnlohmann/jsonでは使えませんでした…
であれば、ファイル読み込みにfstreamを使っていないライブラリに切り替えるぐらいですかね。
ググった感じsimdjsonが速いとの事ですが、いくつか検討されてみてはいかがでしょうか。
みなさん、本当にありがとうございました????♂️
教えていただいたことは知らないことばかりで自分の至らなさを痛感するばかりです。
教えていただいたことは今後に活かしていきます!
回答2件
あなたの回答
tips
プレビュー