-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathevaluate.cpp
More file actions
209 lines (187 loc) · 7.27 KB
/
evaluate.cpp
File metadata and controls
209 lines (187 loc) · 7.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#include <iostream>
#include <fstream>
#include <chrono>
#include <string>
#include <vector>
#ifdef _WIN32
#include <windows.h>
#include <psapi.h> // Include this header for PROCESS_MEMORY_COUNTERS and GetProcessMemoryInfo
#else
#include <unistd.h> // Required for sysconf
#endif
#include <cstdint> // For uint64_t
// Include RapidJSON headers
#include "rapidjson/document.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
// Include simdjson headers
#include "simdjson.h"
using namespace std;
using namespace rapidjson;
using namespace std::chrono;
// Function to get memory usage (resident set size) in KB
long getMemoryUsageKB() {
#ifdef _WIN32
PROCESS_MEMORY_COUNTERS memCounter;
if (GetProcessMemoryInfo(GetCurrentProcess(), &memCounter, sizeof(memCounter))) {
return memCounter.WorkingSetSize / 1024;
}
return 0;
#else
long rss = 0L;
FILE* fp = fopen("/proc/self/statm", "r");
if (fp == nullptr) {
return 0; // Error
}
if (fscanf(fp, "%*s%ld", &rss) != 1) {
fclose(fp);
return 0;
}
fclose(fp);
long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024L;
return rss * page_size_kb;
#endif
}
// Function to check validation speed
bool isValidJson(const string& json_string, bool isSimdJson) {
if (isSimdJson) {
simdjson::dom::parser parser;
auto error = parser.parse(json_string);
return !error.error();
}
Document d;
ParseResult ok = d.Parse(json_string.c_str());
return ok;
}
int main() {
// File path
const string filePath = "5mb_json.json";
string json_string;
{
ifstream inputFile(filePath);
if (!inputFile.is_open()) {
cerr << "Error opening file." << endl;
return 1;
}
json_string = string((istreambuf_iterator<char>(inputFile)),
istreambuf_iterator<char>());
inputFile.close();
}
// RapidJSON parsing
{
cout << "--- RapidJSON ---" << endl;
// Memory Usage
long startMemory = getMemoryUsageKB();
auto start = high_resolution_clock::now();
FILE* fp = fopen(filePath.c_str(), "rb");
if (fp == nullptr) {
cerr << "Error opening file for RapidJSON." << endl;
return 1;
}
char readBuffer[65536];
FileReadStream is(fp, readBuffer, sizeof(readBuffer));
Document d;
d.ParseStream(is);
fclose(fp);
auto end = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(end - start);
cout << "Parsing time: " << duration.count() / 1000 << " ms" << endl;
long endMemory = getMemoryUsageKB();
cout << "Memory usage: " << endMemory - startMemory << " KB" << endl;
// Validation Speed
auto startValidation = high_resolution_clock::now();
bool isValid = isValidJson(json_string, false);
auto endValidation = high_resolution_clock::now();
auto validationDuration = duration_cast<microseconds>(endValidation - startValidation);
cout << "Validation Time : " << validationDuration.count() / 1000 << " ms" << endl;
// Serialization
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
start = high_resolution_clock::now();
d.Accept(writer);
end = high_resolution_clock::now();
duration = duration_cast<microseconds>(end - start);
cout << "Serialization time: " << duration.count() / 1000 << " ms" << endl;
if (d.HasParseError()) {
cout << "Parse Error" << endl;
cout << "Error code: " << d.GetParseError() << endl;
cout << "Error offset: " << d.GetErrorOffset() << endl;
}
// DOM access
if (d.IsObject() && d.HasMember("glossary") && d["glossary"].IsObject()) {
start = high_resolution_clock::now();
const Value& glossary = d["glossary"];
const Value& title = glossary["title"];
if (title.IsString()) {
string str_title = title.GetString();
}
end = high_resolution_clock::now();
duration = duration_cast<microseconds>(end - start);
cout << "DOM access time: " << duration.count() << " microseconds" << endl;
}
}
// simdjson parsing
{
cout << "--- simdjson ---" << endl;
long startMemory = getMemoryUsageKB();
auto start = high_resolution_clock::now();
simdjson::dom::parser parser;
simdjson::dom::element json;
auto error = parser.parse(json_string).get(json);
if (error) {
cerr << "simdjson parse error: " << error << endl;
return 1;
}
auto end = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(end - start);
cout << "Parsing time: " << duration.count() / 1000 << " ms" << endl;
long endMemory = getMemoryUsageKB();
cout << "Memory usage: " << endMemory - startMemory << " KB" << endl;
// Validation Speed
auto startValidation = high_resolution_clock::now();
bool isValid = isValidJson(json_string, true);
auto endValidation = high_resolution_clock::now();
auto validationDuration = duration_cast<microseconds>(endValidation - startValidation);
cout << "Validation Time : " << validationDuration.count() / 1000 << " ms" << endl;
// Serialization
start = high_resolution_clock::now();
string serialized_string = simdjson::to_string(json);
end = high_resolution_clock::now();
duration = duration_cast<microseconds>(end - start);
cout << "Serialization time: " << duration.count() / 1000 << " ms" << endl;
// DOM access
if (json.is_object()) {
start = high_resolution_clock::now();
auto glossary_result = json["glossary"];
if (glossary_result.error()) {
cerr << "simdjson DOM access error getting glossary key: " << glossary_result.error() << endl;
return 1;
}
simdjson::dom::object glossary;
error = glossary_result.get(glossary);
if (error) {
cerr << "simdjson DOM access error : " << error << endl;
return 1;
}
string str_title;
auto title_result = glossary["title"];
if (title_result.error()) {
cerr << "simdjson DOM access error getting title key: " << title_result.error() << endl;
return 1;
}
string_view stringView;
error = title_result.get(stringView);
if (!error) {
str_title = string(stringView);
} else {
cerr << "simdjson DOM access error: " << error << endl;
return 1;
}
end = high_resolution_clock::now();
duration = duration_cast<microseconds>(end - start);
cout << "DOM access time: " << duration.count() << " microseconds" << endl;
}
}
return 0;
}