Skip to content

Commit 474c4e0

Browse files
committed
fix sharedrefs
1 parent 64b5a43 commit 474c4e0

4 files changed

Lines changed: 1046 additions & 208 deletions

File tree

benchmark/benchmark.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
puts " Time: #{elapsed.round(9)} sec"
4848
puts " OPS: #{ops}"
4949

50-
5150
# CBOR Lazy
5251
puts "\nCBOR.decode_lazy"
5352
timer = Chrono::Timer.new
@@ -58,6 +57,18 @@
5857
puts " Time: #{elapsed.round(9)} sec"
5958
puts " OPS: #{ops}"
6059

60+
meta = CBOR::Path.compile("$.search_metadata")
61+
# CBOR Lazy (neues .at)
62+
puts "\nCBOR.decode_lazy.at"
63+
timer = Chrono::Timer.new
64+
result = meta.at(CBOR.decode_lazy(cbor))
65+
elapsed = timer.elapsed
66+
ops = (1.0 / elapsed).round(2)
67+
puts " Result: #{result.inspect}"
68+
puts " Time: #{elapsed.round(9)} sec"
69+
puts " OPS: #{ops}"
70+
71+
6172
# MessagePack Lazy
6273
puts "\nMessagePack.unpack_lazy"
6374
timer = Chrono::Timer.new

benchmark/simdjson_bench.cpp

Lines changed: 84 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#include <chrono>
33
#include <iostream>
44
#include <string>
5+
#include <vector>
6+
#include <variant>
57

68
using Clock = std::chrono::high_resolution_clock;
79

@@ -11,38 +13,9 @@ static void print_header(const std::string &title) {
1113
std::cout << std::string(100, '=') << "\n\n";
1214
}
1315

14-
static void print_object(simdjson::ondemand::object obj) {
15-
std::cout << "{";
16-
bool first = true;
17-
for (auto field : obj) {
18-
if (!first) std::cout << ", ";
19-
first = false;
20-
21-
std::string_view key = field.unescaped_key();
22-
simdjson::ondemand::value val = field.value();
23-
24-
std::cout << "\"" << key << "\" => ";
25-
26-
// Print values similar to Ruby's inspect
27-
switch (val.type()) {
28-
case simdjson::ondemand::json_type::number:
29-
std::cout << double(val);
30-
break;
31-
case simdjson::ondemand::json_type::string:
32-
std::cout << "\"" << std::string(val.get_string().value()) << "\"";
33-
break;
34-
case simdjson::ondemand::json_type::boolean:
35-
std::cout << (bool(val) ? "true" : "false");
36-
break;
37-
case simdjson::ondemand::json_type::null:
38-
std::cout << "nil";
39-
break;
40-
default:
41-
std::cout << "<complex>";
42-
}
43-
}
44-
std::cout << "}";
45-
}
16+
struct Value {
17+
std::variant<double, std::string, bool, std::nullptr_t> data;
18+
};
4619

4720
int main(int argc, char **argv) {
4821
const char *filename = "twitter.json";
@@ -53,80 +26,137 @@ int main(int argc, char **argv) {
5326

5427
// Load file
5528
simdjson::padded_string json = simdjson::padded_string::load(filename);
56-
5729
std::cout << "File: " << filename << " (" << json.size() << " bytes)\n\n";
5830

5931
// EAGER DECODE
6032
print_header("EAGER DECODE BENCHMARK (twitter.json)");
61-
6233
{
6334
std::cout << "simdjson DOM parse\n";
6435
auto start = Clock::now();
65-
6636
simdjson::dom::element doc;
6737
dom_parser.parse(json).get(doc);
68-
6938
auto end = Clock::now();
7039
double elapsed = std::chrono::duration<double>(end - start).count();
7140
double ops = 1.0 / elapsed;
72-
7341
std::cout << " Time: " << elapsed << " sec\n";
7442
std::cout << " OPS: " << ops << "\n\n";
7543
}
7644

7745
// LAZY DECODE
7846
print_header("LAZY DECODE BENCHMARK — /search_metadata");
79-
8047
{
8148
std::cout << "simdjson On-Demand\n";
8249
auto start = Clock::now();
83-
8450
simdjson::ondemand::document doc = ondemand_parser.iterate(json);
8551
simdjson::ondemand::object root = doc.get_object();
8652
simdjson::ondemand::object sm = root["search_metadata"];
87-
53+
// Materialize all fields (equivalent to mruby .value)
54+
std::vector<std::pair<std::string, Value>> fields;
55+
for (auto field : sm) {
56+
std::string key(field.unescaped_key());
57+
simdjson::ondemand::value val = field.value();
58+
Value v;
59+
switch (val.type()) {
60+
case simdjson::ondemand::json_type::number:
61+
v.data = double(val);
62+
break;
63+
case simdjson::ondemand::json_type::string:
64+
v.data = std::string(val.get_string().value());
65+
break;
66+
case simdjson::ondemand::json_type::boolean:
67+
v.data = bool(val);
68+
break;
69+
case simdjson::ondemand::json_type::null:
70+
v.data = nullptr;
71+
break;
72+
default:
73+
break;
74+
}
75+
fields.emplace_back(std::move(key), std::move(v));
76+
}
8877
auto end = Clock::now();
8978
double elapsed = std::chrono::duration<double>(end - start).count();
9079
double ops = 1.0 / elapsed;
91-
92-
std::cout << " Result: ";
93-
print_object(sm);
94-
std::cout << "\n";
95-
80+
// Print result
81+
std::cout << " Result: {";
82+
bool first = true;
83+
for (auto &[k, v] : fields) {
84+
if (!first) std::cout << ", ";
85+
first = false;
86+
std::cout << "\"" << k << "\" => ";
87+
std::visit([](auto &&arg) {
88+
using T = std::decay_t<decltype(arg)>;
89+
if constexpr (std::is_same_v<T, double>) std::cout << arg;
90+
else if constexpr (std::is_same_v<T, std::string>) std::cout << "\"" << arg << "\"";
91+
else if constexpr (std::is_same_v<T, bool>) std::cout << (arg ? "true" : "false");
92+
else if constexpr (std::is_same_v<T, std::nullptr_t>) std::cout << "nil";
93+
}, v.data);
94+
}
95+
std::cout << "}\n";
9696
std::cout << " Time: " << elapsed << " sec\n";
9797
std::cout << " OPS: " << ops << "\n\n";
9898
}
99-
10099
{
101100
std::cout << "simdjson DOM (parse + /search_metadata)\n";
102101
auto start = Clock::now();
103-
104102
simdjson::dom::element doc;
105103
dom_parser.parse(json).get(doc);
106-
107104
simdjson::dom::object root = doc.get_object();
108105
simdjson::dom::object sm = root["search_metadata"];
109-
106+
// Materialize all fields
107+
std::vector<std::pair<std::string, Value>> fields;
108+
for (auto field : sm) {
109+
std::string key(field.key);
110+
Value v;
111+
switch (field.value.type()) {
112+
case simdjson::dom::element_type::DOUBLE:
113+
v.data = double(field.value);
114+
break;
115+
case simdjson::dom::element_type::INT64:
116+
v.data = double(int64_t(field.value));
117+
break;
118+
case simdjson::dom::element_type::UINT64:
119+
v.data = double(uint64_t(field.value));
120+
break;
121+
case simdjson::dom::element_type::STRING:
122+
v.data = std::string(std::string_view(field.value));
123+
break;
124+
case simdjson::dom::element_type::BOOL:
125+
v.data = bool(field.value);
126+
break;
127+
case simdjson::dom::element_type::NULL_VALUE:
128+
v.data = nullptr;
129+
break;
130+
default:
131+
break;
132+
}
133+
fields.emplace_back(std::move(key), std::move(v));
134+
}
110135
auto end = Clock::now();
111136
double elapsed = std::chrono::duration<double>(end - start).count();
112137
double ops = 1.0 / elapsed;
113-
138+
// Print result
114139
std::cout << " Result: {";
115140
bool first = true;
116-
for (auto field : sm) {
141+
for (auto &[k, v] : fields) {
117142
if (!first) std::cout << ", ";
118143
first = false;
119-
std::cout << "\"" << std::string(field.key) << "\" => " << field.value;
144+
std::cout << "\"" << k << "\" => ";
145+
std::visit([](auto &&arg) {
146+
using T = std::decay_t<decltype(arg)>;
147+
if constexpr (std::is_same_v<T, double>) std::cout << arg;
148+
else if constexpr (std::is_same_v<T, std::string>) std::cout << "\"" << arg << "\"";
149+
else if constexpr (std::is_same_v<T, bool>) std::cout << (arg ? "true" : "false");
150+
else if constexpr (std::is_same_v<T, std::nullptr_t>) std::cout << "nil";
151+
}, v.data);
120152
}
121153
std::cout << "}\n";
122-
123154
std::cout << " Time: " << elapsed << " sec\n";
124155
std::cout << " OPS: " << ops << "\n\n";
125156
}
126157

127158
std::cout << std::string(100, '=') << "\n";
128159
std::cout << "Done.\n";
129160
std::cout << std::string(100, '=') << "\n";
130-
131161
return 0;
132162
}

0 commit comments

Comments
 (0)