質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

12782閲覧

c++でjsonファイルを素早く読み込みたい

TRCSQ1

総合スコア1

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/08/25 22:35

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)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tmp

2021/08/25 23:20

ファイルの読み込みがネックになってませんか?とりあえずfstreamのバッファを増やして処理時間が変化するか状況確認を
TRCSQ1

2021/08/25 23:55

一度全ての行について実行時間を計測したのですが、 const std::string path = "a.json"; std::fstream reading(path.c_str()); の部分(=ファイル読み込み)については数十msで処理が終わっていました。 あきらかに、 reading>>jの前後(上下?)を計測した時のみ16000ms〜17000msかかります。 RapidJSONについては、一度試したのですが、jsonファイルに格納されている配列を、変数に代入できない(そちらも同時に原因を探しています。マルチポストはしてません)ので、nlohmanm/jsonを、使っているという状況になります。
FKD

2021/08/26 01:50

std::fstream reading(path.c_str()); はreadingストリームにパス設定しているだけなので、読み込んでいません。 reading >> j; が読み込み&パースです。 また、シンプルにC++のfstreamが遅いので、ファイルI/O速度が重要なら使わない方が良いです。 (他の方法と比べて、群を抜いて遅いレベル)
TRCSQ1

2021/08/26 02:17

初心者なもので、代わりにどう言ったものを使うことを推奨されますか?
FKD

2021/08/26 03:01

私の場合、C++上でなんとかする時は、C言語のfopen系を使います。 (「fstream 遅い」等でググってもらえれば一般論は出てきます) ですが、nlohmann/jsonで使えるかは分からないです。 また、pythonが問題ないとの事だったので、ファイルI/O速度に触れましたが、 どこが遅いかは確認していただいた方がよいかと思います。 ファイルサイズがそれほどでもないなら、パースが遅いはずなので。 ちなみに、プログラムは最適化で構築して計測していますよね?
TRCSQ1

2021/08/26 03:33

すみません、初心者なものでしてVS2019を使っているのですがいつも実行時は「デバッグ無しで実行」を選択しているだけで、最適の掛け方もわかりません。 fopenは試してみます。 fileサイズは18441KBです
FKD

2021/08/26 04:07

(たぶん)18Mくらいならfstreamでも問題ないかな?と思います。 >最適化 この辺りが分からないようであれば、速度を気にする前にVS基礎学習したほうが良いと思います。 ※意味がある状態で計測できていない可能性があります。 とりあえず、上部ツールバーのソリューション構成が「Debug」なら 「Release」に変更してみて計測すると変化ありますか?
TRCSQ1

2021/08/26 05:25

7800〜8500msに高速化しました?! プロパティの最適化オプションについて初めて理解しました。 ありがとうございます????‍♂️ それでもやはり、読み込みに8秒はかかり過ぎ感が否めません…
FKD

2021/08/26 05:34

最適化でパース部分が適正速度になったのだと思います。 ヘッダベースのライブラリと書いてあったので、コンパイル設定にかなり左右されると思われます。 こちらでは最適な設定かは分かりませんので、この辺りは学習願います。 残りのfstream速度に関してはtmpさんが指摘されているように、 バッファサイズを変更して改善があるかを確認されてみてはいかがでしょう。 (fstream バッファサイズ等でググってみてください) それでも遅いようならfopenなりにチャレンジするとよいかと。
TRCSQ1

2021/08/26 05:46

fopenは試しましたが、現在使用しているnlohmann/jsonでは使えませんでした…
FKD

2021/08/26 09:40

であれば、ファイル読み込みにfstreamを使っていないライブラリに切り替えるぐらいですかね。 ググった感じsimdjsonが速いとの事ですが、いくつか検討されてみてはいかがでしょうか。
TRCSQ1

2021/08/26 12:03

みなさん、本当にありがとうございました????‍♂️ 教えていただいたことは知らないことばかりで自分の至らなさを痛感するばかりです。 教えていただいたことは今後に活かしていきます!
guest

回答2

0

ベストアンサー

[回答ではありません]

C++

1#include <vector> 2#include <fstream> 3#include <nlohmann/json.hpp> 4 5int main() { 6 nlohmann::json j = nlohmann::json::parse(std::ifstream("a.json")); 7 8 std::vector<std::string> abc = j["ABC"]; 9 std::cout << abc[1] << std::endl; 10}

コレ↑でも遅いですか?

[追記] コチラ↓はいかがでしょう:

C++

1#include <nlohmann/json.hpp> 2#include <cstdio> 3#include <iostream> 4 5// for convenience 6using json = nlohmann::json; 7 8int main() { 9 FILE* fp = fopen("a.json", "r"); 10 json j = json::parse(fp); 11 fclose(fp); 12 std::cout << j << std::endl; // coutに渡せば出力できる。 13}

投稿2021/08/25 23:14

編集2021/08/26 10:17
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TRCSQ1

2021/08/25 23:21

実行時間17.896でした…
episteme

2021/08/26 09:56

追記しました。いかがなもんでしょ?
TRCSQ1

2021/08/26 12:02

実行時間1100msくらいです!! 凄いです!本当にありがとうございます! 後学の為にも、なぜこれが高速になるのか、または解説リンクを教えていただけますか?
episteme

2021/08/26 13:11

...あれ? 「fopenは試しましたが、現在使用しているnlohmann/jsonでは使えませんでした…」 じゃなかったっけ?
TRCSQ1

2021/08/26 13:32

恥ずかしながら、使い方を誤っていたようです…… parseしないでjson jにfpを入れようとしていました…
guest

0

nlohmann/jsonライブラリの基本動作は「JSONデータ全体を読み込み、事前に内部データ構造を構築する」という動きになっています。XMLパーサやHTMLパーサになぞらえて"DOM-like"とよばれます。

一方で、「入力データ順次処理し、興味のある部分だけを処理する」という動作("SAX-like")も存在します。nlohmann/jsonライブラリは後者のAPIも提供するようですから、一度検討してみてはいかがでしょう。

投稿2021/08/26 00:32

編集2021/08/26 00:33
yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TRCSQ1

2021/08/26 00:43

jsonの中のデータは全て使い、かつ全て最初に変数に格納したいので、そうすると最初から全てを読み込んだ方が楽かもしれません。 SAXの方も試してみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問