simdjson 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.clang-format +5 -0
- data/.gitignore +14 -0
- data/.gitmodules +3 -0
- data/.rubocop.yml +9 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +32 -0
- data/benchmark/apache_builds.json +4421 -0
- data/benchmark/demo.json +15 -0
- data/benchmark/github_events.json +1390 -0
- data/benchmark/run_benchmark.rb +30 -0
- data/ext/simdjson/extconf.rb +22 -0
- data/ext/simdjson/simdjson.cpp +76 -0
- data/ext/simdjson/simdjson.hpp +6 -0
- data/lib/simdjson/version.rb +3 -0
- data/lib/simdjson.rb +2 -0
- data/simdjson.gemspec +35 -0
- data/vendor/.gitkeep +0 -0
- data/vendor/simdjson/AUTHORS +3 -0
- data/vendor/simdjson/CMakeLists.txt +63 -0
- data/vendor/simdjson/CONTRIBUTORS +27 -0
- data/vendor/simdjson/Dockerfile +10 -0
- data/vendor/simdjson/LICENSE +201 -0
- data/vendor/simdjson/Makefile +203 -0
- data/vendor/simdjson/Notes.md +85 -0
- data/vendor/simdjson/README.md +581 -0
- data/vendor/simdjson/amalgamation.sh +158 -0
- data/vendor/simdjson/benchmark/CMakeLists.txt +8 -0
- data/vendor/simdjson/benchmark/benchmark.h +223 -0
- data/vendor/simdjson/benchmark/distinctuseridcompetition.cpp +347 -0
- data/vendor/simdjson/benchmark/linux/linux-perf-events.h +93 -0
- data/vendor/simdjson/benchmark/minifiercompetition.cpp +181 -0
- data/vendor/simdjson/benchmark/parse.cpp +393 -0
- data/vendor/simdjson/benchmark/parseandstatcompetition.cpp +305 -0
- data/vendor/simdjson/benchmark/parsingcompetition.cpp +298 -0
- data/vendor/simdjson/benchmark/statisticalmodel.cpp +208 -0
- data/vendor/simdjson/dependencies/jsoncppdist/json/json-forwards.h +344 -0
- data/vendor/simdjson/dependencies/jsoncppdist/json/json.h +2366 -0
- data/vendor/simdjson/dependencies/jsoncppdist/jsoncpp.cpp +5418 -0
- data/vendor/simdjson/doc/apache_builds.jsonparseandstat.png +0 -0
- data/vendor/simdjson/doc/gbps.png +0 -0
- data/vendor/simdjson/doc/github_events.jsonparseandstat.png +0 -0
- data/vendor/simdjson/doc/twitter.jsonparseandstat.png +0 -0
- data/vendor/simdjson/doc/update-center.jsonparseandstat.png +0 -0
- data/vendor/simdjson/images/halvarflake.png +0 -0
- data/vendor/simdjson/images/logo.png +0 -0
- data/vendor/simdjson/include/simdjson/common_defs.h +102 -0
- data/vendor/simdjson/include/simdjson/isadetection.h +152 -0
- data/vendor/simdjson/include/simdjson/jsoncharutils.h +301 -0
- data/vendor/simdjson/include/simdjson/jsonformatutils.h +202 -0
- data/vendor/simdjson/include/simdjson/jsonioutil.h +32 -0
- data/vendor/simdjson/include/simdjson/jsonminifier.h +30 -0
- data/vendor/simdjson/include/simdjson/jsonparser.h +250 -0
- data/vendor/simdjson/include/simdjson/numberparsing.h +587 -0
- data/vendor/simdjson/include/simdjson/padded_string.h +70 -0
- data/vendor/simdjson/include/simdjson/parsedjson.h +544 -0
- data/vendor/simdjson/include/simdjson/portability.h +172 -0
- data/vendor/simdjson/include/simdjson/simdjson.h +44 -0
- data/vendor/simdjson/include/simdjson/simdjson_version.h +13 -0
- data/vendor/simdjson/include/simdjson/simdprune_tables.h +35074 -0
- data/vendor/simdjson/include/simdjson/simdutf8check_arm64.h +180 -0
- data/vendor/simdjson/include/simdjson/simdutf8check_haswell.h +198 -0
- data/vendor/simdjson/include/simdjson/simdutf8check_westmere.h +169 -0
- data/vendor/simdjson/include/simdjson/stage1_find_marks.h +121 -0
- data/vendor/simdjson/include/simdjson/stage1_find_marks_arm64.h +210 -0
- data/vendor/simdjson/include/simdjson/stage1_find_marks_flatten.h +93 -0
- data/vendor/simdjson/include/simdjson/stage1_find_marks_flatten_haswell.h +95 -0
- data/vendor/simdjson/include/simdjson/stage1_find_marks_haswell.h +210 -0
- data/vendor/simdjson/include/simdjson/stage1_find_marks_macros.h +239 -0
- data/vendor/simdjson/include/simdjson/stage1_find_marks_westmere.h +194 -0
- data/vendor/simdjson/include/simdjson/stage2_build_tape.h +85 -0
- data/vendor/simdjson/include/simdjson/stringparsing.h +105 -0
- data/vendor/simdjson/include/simdjson/stringparsing_arm64.h +56 -0
- data/vendor/simdjson/include/simdjson/stringparsing_haswell.h +43 -0
- data/vendor/simdjson/include/simdjson/stringparsing_macros.h +88 -0
- data/vendor/simdjson/include/simdjson/stringparsing_westmere.h +41 -0
- data/vendor/simdjson/jsonexamples/small/jsoniter_scala/README.md +4 -0
- data/vendor/simdjson/scripts/dumpsimplestats.sh +11 -0
- data/vendor/simdjson/scripts/issue150.sh +14 -0
- data/vendor/simdjson/scripts/javascript/README.md +3 -0
- data/vendor/simdjson/scripts/javascript/generatelargejson.js +19 -0
- data/vendor/simdjson/scripts/minifier.sh +11 -0
- data/vendor/simdjson/scripts/parseandstat.sh +24 -0
- data/vendor/simdjson/scripts/parser.sh +11 -0
- data/vendor/simdjson/scripts/parsingcompdata.sh +26 -0
- data/vendor/simdjson/scripts/plotparse.sh +98 -0
- data/vendor/simdjson/scripts/selectparser.sh +11 -0
- data/vendor/simdjson/scripts/setupfortesting/disablehyperthreading.sh +15 -0
- data/vendor/simdjson/scripts/setupfortesting/powerpolicy.sh +32 -0
- data/vendor/simdjson/scripts/setupfortesting/setupfortesting.sh +6 -0
- data/vendor/simdjson/scripts/setupfortesting/turboboost.sh +51 -0
- data/vendor/simdjson/scripts/testjson2json.sh +99 -0
- data/vendor/simdjson/scripts/transitions/Makefile +10 -0
- data/vendor/simdjson/scripts/transitions/generatetransitions.cpp +20 -0
- data/vendor/simdjson/singleheader/README.md +1 -0
- data/vendor/simdjson/singleheader/amalgamation_demo.cpp +20 -0
- data/vendor/simdjson/singleheader/simdjson.cpp +1652 -0
- data/vendor/simdjson/singleheader/simdjson.h +39692 -0
- data/vendor/simdjson/src/CMakeLists.txt +67 -0
- data/vendor/simdjson/src/jsonioutil.cpp +35 -0
- data/vendor/simdjson/src/jsonminifier.cpp +285 -0
- data/vendor/simdjson/src/jsonparser.cpp +91 -0
- data/vendor/simdjson/src/parsedjson.cpp +323 -0
- data/vendor/simdjson/src/parsedjsoniterator.cpp +272 -0
- data/vendor/simdjson/src/simdjson.cpp +30 -0
- data/vendor/simdjson/src/stage1_find_marks.cpp +41 -0
- data/vendor/simdjson/src/stage2_build_tape.cpp +567 -0
- data/vendor/simdjson/style/clang-format-check.sh +25 -0
- data/vendor/simdjson/style/clang-format.sh +25 -0
- data/vendor/simdjson/style/run-clang-format.py +326 -0
- data/vendor/simdjson/tape.md +134 -0
- data/vendor/simdjson/tests/CMakeLists.txt +25 -0
- data/vendor/simdjson/tests/allparserscheckfile.cpp +192 -0
- data/vendor/simdjson/tests/basictests.cpp +75 -0
- data/vendor/simdjson/tests/jsoncheck.cpp +136 -0
- data/vendor/simdjson/tests/numberparsingcheck.cpp +224 -0
- data/vendor/simdjson/tests/pointercheck.cpp +38 -0
- data/vendor/simdjson/tests/singleheadertest.cpp +22 -0
- data/vendor/simdjson/tests/stringparsingcheck.cpp +408 -0
- data/vendor/simdjson/tools/CMakeLists.txt +3 -0
- data/vendor/simdjson/tools/cmake/FindCTargets.cmake +15 -0
- data/vendor/simdjson/tools/cmake/FindOptions.cmake +52 -0
- data/vendor/simdjson/tools/json2json.cpp +112 -0
- data/vendor/simdjson/tools/jsonpointer.cpp +93 -0
- data/vendor/simdjson/tools/jsonstats.cpp +143 -0
- data/vendor/simdjson/tools/minify.cpp +21 -0
- data/vendor/simdjson/tools/release.py +125 -0
- data/vendor/simdjson/windows/dirent_portable.h +1043 -0
- metadata +273 -0
@@ -0,0 +1,298 @@
|
|
1
|
+
#include "simdjson/jsonparser.h"
|
2
|
+
#ifndef _MSC_VER
|
3
|
+
#include "linux-perf-events.h"
|
4
|
+
#include <unistd.h>
|
5
|
+
#ifdef __linux__
|
6
|
+
#include <libgen.h>
|
7
|
+
#endif //__linux__
|
8
|
+
#endif // _MSC_VER
|
9
|
+
|
10
|
+
#include <memory>
|
11
|
+
|
12
|
+
#include "benchmark.h"
|
13
|
+
|
14
|
+
// #define RAPIDJSON_SSE2 // bad for performance
|
15
|
+
// #define RAPIDJSON_SSE42 // bad for performance
|
16
|
+
#include "rapidjson/document.h"
|
17
|
+
#include "rapidjson/reader.h"
|
18
|
+
#include "rapidjson/stringbuffer.h"
|
19
|
+
#include "rapidjson/writer.h"
|
20
|
+
|
21
|
+
#include "sajson.h"
|
22
|
+
|
23
|
+
#include <nlohmann/json.hpp>
|
24
|
+
using json = nlohmann::json;
|
25
|
+
|
26
|
+
#ifdef ALLPARSER
|
27
|
+
|
28
|
+
#include "fastjson.cpp"
|
29
|
+
#include "fastjson_dom.cpp"
|
30
|
+
#include "gason.cpp"
|
31
|
+
|
32
|
+
#include "json11.cpp"
|
33
|
+
extern "C" {
|
34
|
+
#include "cJSON.c"
|
35
|
+
#include "cJSON.h"
|
36
|
+
#include "jsmn.c"
|
37
|
+
#include "jsmn.h"
|
38
|
+
#include "ujdecode.h"
|
39
|
+
#include "ultrajsondec.c"
|
40
|
+
}
|
41
|
+
|
42
|
+
#include "jsoncpp.cpp"
|
43
|
+
#include "json/json.h"
|
44
|
+
|
45
|
+
#endif
|
46
|
+
|
47
|
+
using namespace rapidjson;
|
48
|
+
|
49
|
+
#ifdef ALLPARSER
|
50
|
+
// fastjson has a tricky interface
|
51
|
+
void on_json_error(void *, const fastjson::ErrorContext &ec) {
|
52
|
+
// std::cerr<<"ERROR: "<<ec.mesg<<std::endl;
|
53
|
+
}
|
54
|
+
bool fastjson_parse(const char *input) {
|
55
|
+
fastjson::Token token;
|
56
|
+
fastjson::dom::Chunk chunk;
|
57
|
+
return fastjson::dom::parse_string(input, &token, &chunk, 0, &on_json_error,
|
58
|
+
NULL);
|
59
|
+
}
|
60
|
+
// end of fastjson stuff
|
61
|
+
#endif
|
62
|
+
|
63
|
+
int main(int argc, char *argv[]) {
|
64
|
+
bool verbose = false;
|
65
|
+
bool just_data = false;
|
66
|
+
int c;
|
67
|
+
while ((c = getopt(argc, argv, "vt")) != -1)
|
68
|
+
switch (c) {
|
69
|
+
case 't':
|
70
|
+
just_data = true;
|
71
|
+
break;
|
72
|
+
case 'v':
|
73
|
+
verbose = true;
|
74
|
+
break;
|
75
|
+
default:
|
76
|
+
abort();
|
77
|
+
}
|
78
|
+
if (optind >= argc) {
|
79
|
+
std::cerr << "Usage: " << argv[0] << " <jsonfile>" << std::endl;
|
80
|
+
std::cerr << "Or " << argv[0] << " -v <jsonfile>" << std::endl;
|
81
|
+
std::cerr << "The '-t' flag outputs a table. " << std::endl;
|
82
|
+
exit(1);
|
83
|
+
}
|
84
|
+
const char *filename = argv[optind];
|
85
|
+
if (optind + 1 < argc) {
|
86
|
+
std::cerr << "warning: ignoring everything after " << argv[optind + 1]
|
87
|
+
<< std::endl;
|
88
|
+
}
|
89
|
+
simdjson::padded_string p;
|
90
|
+
try {
|
91
|
+
simdjson::get_corpus(filename).swap(p);
|
92
|
+
} catch (const std::exception &e) { // caught by reference to base
|
93
|
+
std::cout << "Could not load the file " << filename << std::endl;
|
94
|
+
return EXIT_FAILURE;
|
95
|
+
}
|
96
|
+
|
97
|
+
if (verbose) {
|
98
|
+
std::cout << "Input has ";
|
99
|
+
if (p.size() > 1024 * 1024)
|
100
|
+
std::cout << p.size() / (1024 * 1024) << " MB ";
|
101
|
+
else if (p.size() > 1024)
|
102
|
+
std::cout << p.size() / 1024 << " KB ";
|
103
|
+
else
|
104
|
+
std::cout << p.size() << " B ";
|
105
|
+
std::cout << std::endl;
|
106
|
+
}
|
107
|
+
simdjson::ParsedJson pj;
|
108
|
+
bool allocok = pj.allocate_capacity(p.size(), 1024);
|
109
|
+
|
110
|
+
if (!allocok) {
|
111
|
+
std::cerr << "can't allocate memory" << std::endl;
|
112
|
+
return EXIT_FAILURE;
|
113
|
+
}
|
114
|
+
int repeat = (p.size() < 1 * 1000 * 1000 ? 1000 : 10);
|
115
|
+
int volume = p.size();
|
116
|
+
if (just_data) {
|
117
|
+
printf("%-42s %20s %20s %20s %20s \n", "name", "cycles_per_byte",
|
118
|
+
"cycles_per_byte_err", "gb_per_s", "gb_per_s_err");
|
119
|
+
}
|
120
|
+
if (!just_data)
|
121
|
+
BEST_TIME("simdjson (dynamic mem) ", build_parsed_json(p).is_valid(), true,
|
122
|
+
, repeat, volume, !just_data);
|
123
|
+
// (static alloc)
|
124
|
+
BEST_TIME("simdjson ", json_parse(p, pj), simdjson::SUCCESS, , repeat, volume,
|
125
|
+
!just_data);
|
126
|
+
|
127
|
+
rapidjson::Document d;
|
128
|
+
|
129
|
+
char *buffer = (char *)malloc(p.size() + 1);
|
130
|
+
memcpy(buffer, p.data(), p.size());
|
131
|
+
buffer[p.size()] = '\0';
|
132
|
+
#ifndef ALLPARSER
|
133
|
+
if (!just_data)
|
134
|
+
#endif
|
135
|
+
BEST_TIME("RapidJSON ",
|
136
|
+
d.Parse<kParseValidateEncodingFlag>((const char *)buffer)
|
137
|
+
.HasParseError(),
|
138
|
+
false, memcpy(buffer, p.data(), p.size()), repeat, volume,
|
139
|
+
!just_data);
|
140
|
+
BEST_TIME("RapidJSON (insitu)",
|
141
|
+
d.ParseInsitu<kParseValidateEncodingFlag>(buffer).HasParseError(),
|
142
|
+
false,
|
143
|
+
memcpy(buffer, p.data(), p.size()) && (buffer[p.size()] = '\0'),
|
144
|
+
repeat, volume, !just_data);
|
145
|
+
#ifndef ALLPARSER
|
146
|
+
if (!just_data)
|
147
|
+
#endif
|
148
|
+
BEST_TIME("sajson (dynamic mem)",
|
149
|
+
sajson::parse(sajson::dynamic_allocation(),
|
150
|
+
sajson::mutable_string_view(p.size(), buffer))
|
151
|
+
.is_valid(),
|
152
|
+
true, memcpy(buffer, p.data(), p.size()), repeat, volume,
|
153
|
+
!just_data);
|
154
|
+
|
155
|
+
size_t ast_buffer_size = p.size();
|
156
|
+
size_t *ast_buffer = (size_t *)malloc(ast_buffer_size * sizeof(size_t));
|
157
|
+
// (static alloc, insitu)
|
158
|
+
BEST_TIME(
|
159
|
+
"sajson",
|
160
|
+
sajson::parse(sajson::bounded_allocation(ast_buffer, ast_buffer_size),
|
161
|
+
sajson::mutable_string_view(p.size(), buffer))
|
162
|
+
.is_valid(),
|
163
|
+
true, memcpy(buffer, p.data(), p.size()), repeat, volume, !just_data);
|
164
|
+
size_t expected = json::parse(p.data(), p.data() + p.size()).size();
|
165
|
+
BEST_TIME("nlohmann-json", json::parse(buffer, buffer + p.size()).size(),
|
166
|
+
expected, memcpy(buffer, p.data(), p.size()), repeat, volume,
|
167
|
+
!just_data);
|
168
|
+
|
169
|
+
#ifdef ALLPARSER
|
170
|
+
std::string json11err;
|
171
|
+
BEST_TIME("dropbox (json11) ",
|
172
|
+
((json11::Json::parse(buffer, json11err).is_null()) ||
|
173
|
+
(!json11err.empty())),
|
174
|
+
false, memcpy(buffer, p.data(), p.size()), repeat, volume,
|
175
|
+
!just_data);
|
176
|
+
|
177
|
+
BEST_TIME("fastjson ", fastjson_parse(buffer), true,
|
178
|
+
memcpy(buffer, p.data(), p.size()), repeat, volume, !just_data);
|
179
|
+
JsonValue value;
|
180
|
+
JsonAllocator allocator;
|
181
|
+
char *endptr;
|
182
|
+
BEST_TIME("gason ", jsonParse(buffer, &endptr, &value, allocator),
|
183
|
+
JSON_OK, memcpy(buffer, p.data(), p.size()), repeat, volume,
|
184
|
+
!just_data);
|
185
|
+
void *state;
|
186
|
+
BEST_TIME("ultrajson ",
|
187
|
+
(UJDecode(buffer, p.size(), NULL, &state) == NULL), false,
|
188
|
+
memcpy(buffer, p.data(), p.size()), repeat, volume, !just_data);
|
189
|
+
|
190
|
+
{
|
191
|
+
std::unique_ptr<jsmntok_t[]> tokens =
|
192
|
+
std::make_unique<jsmntok_t[]>(p.size());
|
193
|
+
jsmn_parser parser;
|
194
|
+
jsmn_init(&parser);
|
195
|
+
memcpy(buffer, p.data(), p.size());
|
196
|
+
buffer[p.size()] = '\0';
|
197
|
+
BEST_TIME(
|
198
|
+
"jsmn ",
|
199
|
+
(jsmn_parse(&parser, buffer, p.size(), tokens.get(), p.size()) > 0),
|
200
|
+
true, jsmn_init(&parser), repeat, volume, !just_data);
|
201
|
+
}
|
202
|
+
memcpy(buffer, p.data(), p.size());
|
203
|
+
buffer[p.size()] = '\0';
|
204
|
+
cJSON *tree = cJSON_Parse(buffer);
|
205
|
+
BEST_TIME("cJSON ", ((tree = cJSON_Parse(buffer)) != NULL), true,
|
206
|
+
cJSON_Delete(tree), repeat, volume, !just_data);
|
207
|
+
cJSON_Delete(tree);
|
208
|
+
|
209
|
+
Json::CharReaderBuilder b;
|
210
|
+
Json::CharReader *json_cpp_reader = b.newCharReader();
|
211
|
+
Json::Value root;
|
212
|
+
Json::String errs;
|
213
|
+
BEST_TIME("jsoncpp ",
|
214
|
+
json_cpp_reader->parse(buffer, buffer + volume, &root, &errs), true,
|
215
|
+
, repeat, volume, !just_data);
|
216
|
+
delete json_cpp_reader;
|
217
|
+
#endif
|
218
|
+
if (!just_data)
|
219
|
+
BEST_TIME("memcpy ",
|
220
|
+
(memcpy(buffer, p.data(), p.size()) == buffer), true, , repeat,
|
221
|
+
volume, !just_data);
|
222
|
+
#ifdef __linux__
|
223
|
+
if (!just_data) {
|
224
|
+
printf("\n \n <doing additional analysis with performance counters (Linux "
|
225
|
+
"only)>\n");
|
226
|
+
std::vector<int> evts;
|
227
|
+
evts.push_back(PERF_COUNT_HW_CPU_CYCLES);
|
228
|
+
evts.push_back(PERF_COUNT_HW_INSTRUCTIONS);
|
229
|
+
evts.push_back(PERF_COUNT_HW_BRANCH_MISSES);
|
230
|
+
evts.push_back(PERF_COUNT_HW_CACHE_REFERENCES);
|
231
|
+
evts.push_back(PERF_COUNT_HW_CACHE_MISSES);
|
232
|
+
LinuxEvents<PERF_TYPE_HARDWARE> unified(evts);
|
233
|
+
std::vector<unsigned long long> results;
|
234
|
+
std::vector<unsigned long long> stats;
|
235
|
+
results.resize(evts.size());
|
236
|
+
stats.resize(evts.size());
|
237
|
+
std::fill(stats.begin(), stats.end(), 0); // unnecessary
|
238
|
+
for (int i = 0; i < repeat; i++) {
|
239
|
+
unified.start();
|
240
|
+
if (json_parse(p, pj) != simdjson::SUCCESS)
|
241
|
+
printf("bug\n");
|
242
|
+
unified.end(results);
|
243
|
+
std::transform(stats.begin(), stats.end(), results.begin(), stats.begin(),
|
244
|
+
std::plus<unsigned long long>());
|
245
|
+
}
|
246
|
+
printf("simdjson : cycles %10.0f instructions %10.0f branchmisses %10.0f "
|
247
|
+
"cacheref %10.0f cachemisses %10.0f bytespercachemiss %10.0f "
|
248
|
+
"inspercycle %10.1f insperbyte %10.1f\n",
|
249
|
+
stats[0] * 1.0 / repeat, stats[1] * 1.0 / repeat,
|
250
|
+
stats[2] * 1.0 / repeat, stats[3] * 1.0 / repeat,
|
251
|
+
stats[4] * 1.0 / repeat, volume * repeat * 1.0 / stats[2],
|
252
|
+
stats[1] * 1.0 / stats[0], stats[1] * 1.0 / (volume * repeat));
|
253
|
+
|
254
|
+
std::fill(stats.begin(), stats.end(), 0);
|
255
|
+
for (int i = 0; i < repeat; i++) {
|
256
|
+
memcpy(buffer, p.data(), p.size());
|
257
|
+
buffer[p.size()] = '\0';
|
258
|
+
unified.start();
|
259
|
+
if (d.ParseInsitu<kParseValidateEncodingFlag>(buffer).HasParseError() !=
|
260
|
+
false)
|
261
|
+
printf("bug\n");
|
262
|
+
unified.end(results);
|
263
|
+
std::transform(stats.begin(), stats.end(), results.begin(), stats.begin(),
|
264
|
+
std::plus<unsigned long long>());
|
265
|
+
}
|
266
|
+
printf("RapidJSON: cycles %10.0f instructions %10.0f branchmisses %10.0f "
|
267
|
+
"cacheref %10.0f cachemisses %10.0f bytespercachemiss %10.0f "
|
268
|
+
"inspercycle %10.1f insperbyte %10.1f\n",
|
269
|
+
stats[0] * 1.0 / repeat, stats[1] * 1.0 / repeat,
|
270
|
+
stats[2] * 1.0 / repeat, stats[3] * 1.0 / repeat,
|
271
|
+
stats[4] * 1.0 / repeat, volume * repeat * 1.0 / stats[2],
|
272
|
+
stats[1] * 1.0 / stats[0], stats[1] * 1.0 / (volume * repeat));
|
273
|
+
|
274
|
+
std::fill(stats.begin(), stats.end(), 0); // unnecessary
|
275
|
+
for (int i = 0; i < repeat; i++) {
|
276
|
+
memcpy(buffer, p.data(), p.size());
|
277
|
+
unified.start();
|
278
|
+
if (sajson::parse(sajson::bounded_allocation(ast_buffer, ast_buffer_size),
|
279
|
+
sajson::mutable_string_view(p.size(), buffer))
|
280
|
+
.is_valid() != true)
|
281
|
+
printf("bug\n");
|
282
|
+
unified.end(results);
|
283
|
+
std::transform(stats.begin(), stats.end(), results.begin(), stats.begin(),
|
284
|
+
std::plus<unsigned long long>());
|
285
|
+
}
|
286
|
+
printf("sajson : cycles %10.0f instructions %10.0f branchmisses %10.0f "
|
287
|
+
"cacheref %10.0f cachemisses %10.0f bytespercachemiss %10.0f "
|
288
|
+
"inspercycle %10.1f insperbyte %10.1f\n",
|
289
|
+
stats[0] * 1.0 / repeat, stats[1] * 1.0 / repeat,
|
290
|
+
stats[2] * 1.0 / repeat, stats[3] * 1.0 / repeat,
|
291
|
+
stats[4] * 1.0 / repeat, volume * repeat * 1.0 / stats[2],
|
292
|
+
stats[1] * 1.0 / stats[0], stats[1] * 1.0 / (volume * repeat));
|
293
|
+
}
|
294
|
+
#endif // __linux__
|
295
|
+
|
296
|
+
free(ast_buffer);
|
297
|
+
free(buffer);
|
298
|
+
}
|
@@ -0,0 +1,208 @@
|
|
1
|
+
#include <iostream>
|
2
|
+
#ifndef _MSC_VER
|
3
|
+
#include <unistd.h>
|
4
|
+
#endif
|
5
|
+
#include "simdjson/jsonioutil.h"
|
6
|
+
#include "simdjson/jsonparser.h"
|
7
|
+
#ifdef __linux__
|
8
|
+
#include "linux-perf-events.h"
|
9
|
+
#endif
|
10
|
+
|
11
|
+
size_t count_nonasciibytes(const uint8_t *input, size_t length) {
|
12
|
+
size_t count = 0;
|
13
|
+
for (size_t i = 0; i < length; i++) {
|
14
|
+
count += input[i] >> 7;
|
15
|
+
}
|
16
|
+
return count;
|
17
|
+
}
|
18
|
+
|
19
|
+
size_t count_backslash(const uint8_t *input, size_t length) {
|
20
|
+
size_t count = 0;
|
21
|
+
for (size_t i = 0; i < length; i++) {
|
22
|
+
count += (input[i] == '\\') ? 1 : 0;
|
23
|
+
}
|
24
|
+
return count;
|
25
|
+
}
|
26
|
+
|
27
|
+
struct stat_s {
|
28
|
+
size_t integer_count;
|
29
|
+
size_t float_count;
|
30
|
+
size_t string_count;
|
31
|
+
size_t backslash_count;
|
32
|
+
size_t non_ascii_byte_count;
|
33
|
+
size_t object_count;
|
34
|
+
size_t array_count;
|
35
|
+
size_t null_count;
|
36
|
+
size_t true_count;
|
37
|
+
size_t false_count;
|
38
|
+
size_t byte_count;
|
39
|
+
size_t structural_indexes_count;
|
40
|
+
bool valid;
|
41
|
+
};
|
42
|
+
|
43
|
+
using stat_t = struct stat_s;
|
44
|
+
|
45
|
+
stat_t simdjson_compute_stats(const simdjson::padded_string &p) {
|
46
|
+
stat_t answer;
|
47
|
+
simdjson::ParsedJson pj = simdjson::build_parsed_json(p);
|
48
|
+
answer.valid = pj.is_valid();
|
49
|
+
if (!answer.valid) {
|
50
|
+
return answer;
|
51
|
+
}
|
52
|
+
answer.backslash_count =
|
53
|
+
count_backslash(reinterpret_cast<const uint8_t *>(p.data()), p.size());
|
54
|
+
answer.non_ascii_byte_count = count_nonasciibytes(
|
55
|
+
reinterpret_cast<const uint8_t *>(p.data()), p.size());
|
56
|
+
answer.byte_count = p.size();
|
57
|
+
answer.integer_count = 0;
|
58
|
+
answer.float_count = 0;
|
59
|
+
answer.object_count = 0;
|
60
|
+
answer.array_count = 0;
|
61
|
+
answer.null_count = 0;
|
62
|
+
answer.true_count = 0;
|
63
|
+
answer.false_count = 0;
|
64
|
+
answer.string_count = 0;
|
65
|
+
answer.structural_indexes_count = pj.n_structural_indexes;
|
66
|
+
size_t tape_idx = 0;
|
67
|
+
uint64_t tape_val = pj.tape[tape_idx++];
|
68
|
+
uint8_t type = (tape_val >> 56);
|
69
|
+
size_t how_many = 0;
|
70
|
+
assert(type == 'r');
|
71
|
+
how_many = tape_val & JSON_VALUE_MASK;
|
72
|
+
for (; tape_idx < how_many; tape_idx++) {
|
73
|
+
tape_val = pj.tape[tape_idx];
|
74
|
+
// uint64_t payload = tape_val & JSON_VALUE_MASK;
|
75
|
+
type = (tape_val >> 56);
|
76
|
+
switch (type) {
|
77
|
+
case 'l': // we have a long int
|
78
|
+
answer.integer_count++;
|
79
|
+
tape_idx++; // skipping the integer
|
80
|
+
break;
|
81
|
+
case 'd': // we have a double
|
82
|
+
answer.float_count++;
|
83
|
+
tape_idx++; // skipping the double
|
84
|
+
break;
|
85
|
+
case 'n': // we have a null
|
86
|
+
answer.null_count++;
|
87
|
+
break;
|
88
|
+
case 't': // we have a true
|
89
|
+
answer.true_count++;
|
90
|
+
break;
|
91
|
+
case 'f': // we have a false
|
92
|
+
answer.false_count++;
|
93
|
+
break;
|
94
|
+
case '{': // we have an object
|
95
|
+
answer.object_count++;
|
96
|
+
break;
|
97
|
+
case '}': // we end an object
|
98
|
+
break;
|
99
|
+
case '[': // we start an array
|
100
|
+
answer.array_count++;
|
101
|
+
break;
|
102
|
+
case ']': // we end an array
|
103
|
+
break;
|
104
|
+
case '"': // we have a string
|
105
|
+
answer.string_count++;
|
106
|
+
break;
|
107
|
+
default:
|
108
|
+
break; // ignore
|
109
|
+
}
|
110
|
+
}
|
111
|
+
return answer;
|
112
|
+
}
|
113
|
+
|
114
|
+
int main(int argc, char *argv[]) {
|
115
|
+
#ifndef _MSC_VER
|
116
|
+
int c;
|
117
|
+
while ((c = getopt(argc, argv, "")) != -1) {
|
118
|
+
switch (c) {
|
119
|
+
|
120
|
+
default:
|
121
|
+
abort();
|
122
|
+
}
|
123
|
+
}
|
124
|
+
#else
|
125
|
+
int optind = 1;
|
126
|
+
#endif
|
127
|
+
if (optind >= argc) {
|
128
|
+
std::cerr << "Reads json, prints stats. " << std::endl;
|
129
|
+
std::cerr << "Usage: " << argv[0] << " <jsonfile>" << std::endl;
|
130
|
+
|
131
|
+
exit(1);
|
132
|
+
}
|
133
|
+
const char *filename = argv[optind];
|
134
|
+
if (optind + 1 < argc) {
|
135
|
+
std::cerr << "warning: ignoring everything after " << argv[optind + 1]
|
136
|
+
<< std::endl;
|
137
|
+
}
|
138
|
+
simdjson::padded_string p;
|
139
|
+
try {
|
140
|
+
simdjson::get_corpus(filename).swap(p);
|
141
|
+
} catch (const std::exception &) { // caught by reference to base
|
142
|
+
std::cerr << "Could not load the file " << filename << std::endl;
|
143
|
+
return EXIT_FAILURE;
|
144
|
+
}
|
145
|
+
stat_t s = simdjson_compute_stats(p);
|
146
|
+
if (!s.valid) {
|
147
|
+
std::cerr << "not a valid JSON" << std::endl;
|
148
|
+
return EXIT_FAILURE;
|
149
|
+
}
|
150
|
+
|
151
|
+
printf("# integer_count float_count string_count backslash_count "
|
152
|
+
"non_ascii_byte_count object_count array_count null_count true_count "
|
153
|
+
"false_count byte_count structural_indexes_count ");
|
154
|
+
#ifdef __linux__
|
155
|
+
printf(" stage1_cycle_count stage1_instruction_count stage2_cycle_count "
|
156
|
+
" stage2_instruction_count stage3_cycle_count "
|
157
|
+
"stage3_instruction_count ");
|
158
|
+
#else
|
159
|
+
printf("(you are not under linux, so perf counters are disaabled)");
|
160
|
+
#endif
|
161
|
+
printf("\n");
|
162
|
+
printf("%zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu ", s.integer_count,
|
163
|
+
s.float_count, s.string_count, s.backslash_count,
|
164
|
+
s.non_ascii_byte_count, s.object_count, s.array_count, s.null_count,
|
165
|
+
s.true_count, s.false_count, s.byte_count, s.structural_indexes_count);
|
166
|
+
#ifdef __linux__
|
167
|
+
simdjson::ParsedJson pj;
|
168
|
+
bool allocok = pj.allocate_capacity(p.size());
|
169
|
+
if (!allocok) {
|
170
|
+
std::cerr << "failed to allocate memory" << std::endl;
|
171
|
+
return EXIT_FAILURE;
|
172
|
+
}
|
173
|
+
const uint32_t iterations = p.size() < 1 * 1000 * 1000 ? 1000 : 50;
|
174
|
+
std::vector<int> evts;
|
175
|
+
evts.push_back(PERF_COUNT_HW_CPU_CYCLES);
|
176
|
+
evts.push_back(PERF_COUNT_HW_INSTRUCTIONS);
|
177
|
+
LinuxEvents<PERF_TYPE_HARDWARE> unified(evts);
|
178
|
+
unsigned long cy1 = 0, cy2 = 0;
|
179
|
+
unsigned long cl1 = 0, cl2 = 0;
|
180
|
+
std::vector<unsigned long long> results;
|
181
|
+
results.resize(evts.size());
|
182
|
+
for (uint32_t i = 0; i < iterations; i++) {
|
183
|
+
unified.start();
|
184
|
+
// The default template is simdjson::Architecture::NATIVE.
|
185
|
+
bool isok = (simdjson::find_structural_bits<>(p.data(), p.size(), pj) ==
|
186
|
+
simdjson::SUCCESS);
|
187
|
+
unified.end(results);
|
188
|
+
|
189
|
+
cy1 += results[0];
|
190
|
+
cl1 += results[1];
|
191
|
+
|
192
|
+
unified.start();
|
193
|
+
isok =
|
194
|
+
isok && (simdjson::SUCCESS == unified_machine(p.data(), p.size(), pj));
|
195
|
+
unified.end(results);
|
196
|
+
|
197
|
+
cy2 += results[0];
|
198
|
+
cl2 += results[1];
|
199
|
+
if (!isok) {
|
200
|
+
std::cerr << "failure?" << std::endl;
|
201
|
+
}
|
202
|
+
}
|
203
|
+
printf("%f %f %f %f ", cy1 * 1.0 / iterations, cl1 * 1.0 / iterations,
|
204
|
+
cy2 * 1.0 / iterations, cl2 * 1.0 / iterations);
|
205
|
+
#endif // __linux__
|
206
|
+
printf("\n");
|
207
|
+
return EXIT_SUCCESS;
|
208
|
+
}
|