Schneller & einfacher JSONLines-Prozessor in C++ mit boost::json
Dieses Beispiel parst eine jsonlines-Datei (eine Datei mit einem JSON-Objekt pro Zeile) und gibt das name-Feld jedes Objekts aus.
Dieser Code wurde nicht speziell auf Leistung optimiert, sondern als Kompromiss zwischen Leistung und Lesbarkeit. Er sollte für die meisten Anwendungsfälle schnell genug sein.
jsonlines_processor.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <boost/json.hpp>
class JSONLineProcessor {
public:
JSONLineProcessor(const std::string& filename) : file(filename) {
if (!file.is_open()) {
throw std::runtime_error("Error: Could not open file.");
}
}
void process_lines() {
std::string line;
while (std::getline(file, line)) {
process_line(line);
}
}
private:
std::ifstream file;
void process_line(const std::string& line) {
try {
// Parse the JSON line
boost::json::value json_value = boost::json::parse(line);
// Check if it's a JSON object
if (json_value.is_object()) {
process_json(json_value.as_object());
} else {
std::cerr << "Error: Parsed value is not a JSON object." << std::endl;
}
} catch (const boost::json::system_error& e) {
// Handle parsing errors
std::cerr << "Error parsing JSON line: " << e.what() << std::endl;
}
}
void process_json(const boost::json::object& obj) {
// For the sake of example, just print the json["timestamp"] value
auto _timestamp = obj.at("timestamp");
if (_timestamp.is_double()) {
double timestamp = obj.at("timestamp").as_double();
std::cout << obj.at("timestamp").as_double() << std::endl;
}
}
};
int main(int argc, char** argv) {
if(argc <= 1) {
std::cerr << "Usage: " << argv[0] << std::endl;
return 1;
}
try {
JSONLineProcessor processor(argv[1]);
processor.process_lines();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
}
return 0;
}Wie man kompiliert
compile_jsonlines_processor.sh
g++ -O3 -std=c++17 -lboost_json -o jsonlines_processor jsonlines_processor.cppLeistung
Kompilieren mit
compile_jsonlines_optimized.sh
g++ -march=native -O2 -std=gnu++17 -lboost_json -o jsonlines_processor jsonlines_processor.cppund ausführen mit
run_jsonlines_benchmark.sh
time ./jsonlines_processor filename.jsonlines > /dev/nullauf einer 4,5 GB jsonlines-Datei mit 4442720 (4,4M) Zeilen dauert 36,4 Sekunden (Bestes von 3 Läufen), was einen Durchsatz von 123,6 MB/s und 122k JSON-Zeilen pro Sekunde auf meinem Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz ergibt.
Dieses Programm nutzt kein Multi-Threading
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow