Get rid of templates from rapidjson benchmarks

This commit is contained in:
John Keiser 2021-01-04 20:20:24 -08:00
parent 065ea00066
commit 6a595231b0
21 changed files with 75 additions and 62 deletions

View File

@ -8,13 +8,10 @@ namespace distinct_user_id {
using namespace rapidjson; using namespace rapidjson;
template<int F> struct rapidjson_base {
class rapidjson_base {
Document doc{}; Document doc{};
public: bool run(Document &root, std::vector<uint64_t> &ids) {
bool run(const padded_string &json, std::vector<uint64_t> &ids) {
auto &root = doc.Parse<F>(json.data());
if (root.HasParseError() || !root.IsObject()) { return false; } if (root.HasParseError() || !root.IsObject()) { return false; }
auto statuses = root.FindMember("statuses"); auto statuses = root.FindMember("statuses");
if (statuses == root.MemberEnd() || !statuses->value.IsArray()) { return false; } if (statuses == root.MemberEnd() || !statuses->value.IsArray()) { return false; }
@ -41,7 +38,12 @@ public:
} }
}; };
class rapidjson : public rapidjson_base<kParseValidateEncodingFlag> {}; struct rapidjson : public rapidjson_base {
bool run(const padded_string &json, std::vector<uint64_t> &ids) {
return rapidjson_base::run(doc.Parse<kParseValidateEncodingFlag>(json.data()), ids);
}
};
BENCHMARK_TEMPLATE(distinct_user_id, rapidjson); BENCHMARK_TEMPLATE(distinct_user_id, rapidjson);
} // namespace partial_tweets } // namespace partial_tweets

View File

@ -8,7 +8,7 @@ namespace distinct_user_id {
using namespace simdjson; using namespace simdjson;
class simdjson_dom { struct simdjson_dom {
dom::parser parser{}; dom::parser parser{};
public: public:

View File

@ -9,7 +9,7 @@ namespace distinct_user_id {
using namespace simdjson; using namespace simdjson;
using namespace simdjson::builtin; using namespace simdjson::builtin;
class simdjson_ondemand { struct simdjson_ondemand {
ondemand::parser parser{}; ondemand::parser parser{};
public: public:
bool run(const simdjson::padded_string &json, std::vector<uint64_t> &ids) { bool run(const simdjson::padded_string &json, std::vector<uint64_t> &ids) {

View File

@ -6,7 +6,7 @@
namespace distinct_user_id { namespace distinct_user_id {
class yyjson { struct yyjson {
public: public:
bool run(const simdjson::padded_string &json, std::vector<uint64_t> &ids) { bool run(const simdjson::padded_string &json, std::vector<uint64_t> &ids) {
// Walk the document, parsing the tweets as we go // Walk the document, parsing the tweets as we go

View File

@ -8,13 +8,10 @@ namespace find_tweet {
using namespace rapidjson; using namespace rapidjson;
template<int F> struct rapidjson_base {
class rapidjson_base {
Document doc{}; Document doc{};
public: bool run(Document &root, uint64_t find_id, std::string_view &text) {
bool run(const padded_string &json, uint64_t find_id, std::string_view &text) {
auto &root = doc.Parse<F>(json.data());
if (root.HasParseError() || !root.IsObject()) { return false; } if (root.HasParseError() || !root.IsObject()) { return false; }
auto statuses = root.FindMember("statuses"); auto statuses = root.FindMember("statuses");
if (statuses == root.MemberEnd() || !statuses->value.IsArray()) { return false; } if (statuses == root.MemberEnd() || !statuses->value.IsArray()) { return false; }
@ -34,7 +31,11 @@ public:
} }
}; };
class rapidjson : public rapidjson_base<kParseValidateEncodingFlag> {}; struct rapidjson : public rapidjson_base {
bool run(const padded_string &json, uint64_t find_id, std::string_view &text) {
return rapidjson_base::run(doc.Parse<kParseValidateEncodingFlag>(json.data()), find_id, text);
}
};
BENCHMARK_TEMPLATE(find_tweet, rapidjson); BENCHMARK_TEMPLATE(find_tweet, rapidjson);
} // namespace partial_tweets } // namespace partial_tweets

View File

@ -8,9 +8,9 @@ namespace find_tweet {
using namespace simdjson; using namespace simdjson;
class simdjson_dom { struct simdjson_dom {
dom::parser parser{}; dom::parser parser{};
public:
bool run(const simdjson::padded_string &json, uint64_t find_id, std::string_view &text) { bool run(const simdjson::padded_string &json, uint64_t find_id, std::string_view &text) {
text = ""; text = "";
auto doc = parser.parse(json); auto doc = parser.parse(json);

View File

@ -9,9 +9,9 @@ namespace find_tweet {
using namespace simdjson; using namespace simdjson;
using namespace simdjson::builtin; using namespace simdjson::builtin;
class simdjson_ondemand { struct simdjson_ondemand {
ondemand::parser parser{}; ondemand::parser parser{};
public:
bool run(const simdjson::padded_string &json, uint64_t find_id, std::string_view &text) { bool run(const simdjson::padded_string &json, uint64_t find_id, std::string_view &text) {
// Walk the document, parsing as we go // Walk the document, parsing as we go
auto doc = parser.iterate(json); auto doc = parser.iterate(json);

View File

@ -6,8 +6,7 @@
namespace find_tweet { namespace find_tweet {
class yyjson { struct yyjson {
public:
bool run(const simdjson::padded_string &json, uint64_t find_id, std::string_view &text) { bool run(const simdjson::padded_string &json, uint64_t find_id, std::string_view &text) {
// Walk the document, parsing the tweets as we go // Walk the document, parsing the tweets as we go
yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0); yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0);

View File

@ -8,8 +8,7 @@ namespace kostya {
using namespace rapidjson; using namespace rapidjson;
template<int F> struct rapidjson_base {
class rapidjson_base {
Document doc; Document doc;
simdjson_really_inline double get_double(Value &object, std::string_view key) { simdjson_really_inline double get_double(Value &object, std::string_view key) {
@ -19,9 +18,7 @@ class rapidjson_base {
return field->value.GetDouble(); return field->value.GetDouble();
} }
public: bool run(Document &root, std::vector<point> &points) {
bool run(const simdjson::padded_string &json, std::vector<point> &points) {
auto &root = doc.Parse<F>(json.data());
if (root.HasParseError()) { return false; } if (root.HasParseError()) { return false; }
if (!root.IsObject()) { return false; } if (!root.IsObject()) { return false; }
auto coords = root.FindMember("coordinates"); auto coords = root.FindMember("coordinates");
@ -36,8 +33,18 @@ public:
} }
}; };
class rapidjson : public rapidjson_base<kParseValidateEncodingFlag> {}; struct rapidjson : public rapidjson_base {
class rapidjson_lossless : public rapidjson_base<kParseValidateEncodingFlag | kParseFullPrecisionFlag> {}; bool run(const padded_string &json, std::vector<point> &points) {
return rapidjson_base::run(doc.Parse<kParseValidateEncodingFlag>(json.data()), points);
}
};
struct rapidjson_lossless : public rapidjson_base {
bool run(const padded_string &json, std::vector<point> &points) {
return rapidjson_base::run(doc.Parse<kParseValidateEncodingFlag | kParseFullPrecisionFlag>(json.data()), points);
}
};
BENCHMARK_TEMPLATE(kostya, rapidjson); BENCHMARK_TEMPLATE(kostya, rapidjson);
BENCHMARK_TEMPLATE(kostya, rapidjson_lossless); BENCHMARK_TEMPLATE(kostya, rapidjson_lossless);

View File

@ -8,9 +8,9 @@ namespace kostya {
using namespace simdjson; using namespace simdjson;
class simdjson_dom { struct simdjson_dom {
dom::parser parser{}; dom::parser parser{};
public:
bool run(const simdjson::padded_string &json, std::vector<point> &points) { bool run(const simdjson::padded_string &json, std::vector<point> &points) {
for (auto point : parser.parse(json)["coordinates"]) { for (auto point : parser.parse(json)["coordinates"]) {
points.emplace_back(kostya::point{point["x"], point["y"], point["z"]}); points.emplace_back(kostya::point{point["x"], point["y"], point["z"]});

View File

@ -9,9 +9,9 @@ namespace kostya {
using namespace simdjson; using namespace simdjson;
using namespace simdjson::builtin; using namespace simdjson::builtin;
class simdjson_ondemand { struct simdjson_ondemand {
ondemand::parser parser{}; ondemand::parser parser{};
public:
bool run(const simdjson::padded_string &json, std::vector<point> &points) { bool run(const simdjson::padded_string &json, std::vector<point> &points) {
auto doc = parser.iterate(json); auto doc = parser.iterate(json);
for (ondemand::object point : doc.find_field("coordinates")) { for (ondemand::object point : doc.find_field("coordinates")) {

View File

@ -6,7 +6,7 @@
namespace kostya { namespace kostya {
class yyjson { struct yyjson {
simdjson_really_inline double get_double(yyjson_val *obj, std::string_view key) { simdjson_really_inline double get_double(yyjson_val *obj, std::string_view key) {
yyjson_val *val = yyjson_obj_getn(obj, key.data(), key.length()); yyjson_val *val = yyjson_obj_getn(obj, key.data(), key.length());
if (!val) { throw "missing point field!"; } if (!val) { throw "missing point field!"; }
@ -24,7 +24,6 @@ class yyjson {
} }
} }
public:
bool run(const simdjson::padded_string &json, std::vector<point> &points) { bool run(const simdjson::padded_string &json, std::vector<point> &points) {
yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0); yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0);
if (!doc) { return false; } if (!doc) { return false; }

View File

@ -8,8 +8,7 @@ namespace large_random {
using namespace rapidjson; using namespace rapidjson;
template<int F> struct rapidjson_base {
class rapidjson_base {
Document doc; Document doc;
simdjson_really_inline double get_double(Value &object, std::string_view key) { simdjson_really_inline double get_double(Value &object, std::string_view key) {
@ -19,9 +18,7 @@ class rapidjson_base {
return field->value.GetDouble(); return field->value.GetDouble();
} }
public: bool run(Document &coords, std::vector<point> &points) {
bool run(const simdjson::padded_string &json, std::vector<point> &points) {
auto &coords = doc.Parse<F>(json.data());
if (coords.HasParseError()) { return false; } if (coords.HasParseError()) { return false; }
if (!coords.IsArray()) { return false; } if (!coords.IsArray()) { return false; }
for (auto &coord : coords.GetArray()) { for (auto &coord : coords.GetArray()) {
@ -33,8 +30,18 @@ public:
} }
}; };
class rapidjson : public rapidjson_base<kParseValidateEncodingFlag> {}; struct rapidjson : public rapidjson_base {
class rapidjson_lossless : public rapidjson_base<kParseValidateEncodingFlag | kParseFullPrecisionFlag> {}; bool run(const simdjson::padded_string &json, std::vector<point> &points) {
return rapidjson_base::run(doc.Parse<kParseValidateEncodingFlag>(json.data()), points);
}
};
struct rapidjson_lossless : public rapidjson_base {
bool run(const simdjson::padded_string &json, std::vector<point> &points) {
return rapidjson_base::run(doc.Parse<kParseValidateEncodingFlag | kParseFullPrecisionFlag>(json.data()), points);
}
};
BENCHMARK_TEMPLATE(large_random, rapidjson); BENCHMARK_TEMPLATE(large_random, rapidjson);
BENCHMARK_TEMPLATE(large_random, rapidjson_lossless); BENCHMARK_TEMPLATE(large_random, rapidjson_lossless);

View File

@ -8,9 +8,9 @@ namespace large_random {
using namespace simdjson; using namespace simdjson;
class simdjson_dom { struct simdjson_dom {
dom::parser parser{}; dom::parser parser{};
public:
bool run(const simdjson::padded_string &json, std::vector<point> &points) { bool run(const simdjson::padded_string &json, std::vector<point> &points) {
for (auto point : parser.parse(json)) { for (auto point : parser.parse(json)) {
points.emplace_back(large_random::point{point["x"], point["y"], point["z"]}); points.emplace_back(large_random::point{point["x"], point["y"], point["z"]});

View File

@ -9,9 +9,9 @@ namespace large_random {
using namespace simdjson; using namespace simdjson;
using namespace simdjson::builtin; using namespace simdjson::builtin;
class simdjson_ondemand { struct simdjson_ondemand {
ondemand::parser parser{}; ondemand::parser parser{};
public:
bool run(const simdjson::padded_string &json, std::vector<point> &points) { bool run(const simdjson::padded_string &json, std::vector<point> &points) {
auto doc = parser.iterate(json); auto doc = parser.iterate(json);
for (ondemand::object coord : doc) { for (ondemand::object coord : doc) {

View File

@ -9,9 +9,9 @@ namespace large_random {
using namespace simdjson; using namespace simdjson;
using namespace simdjson::builtin; using namespace simdjson::builtin;
class simdjson_ondemand_unordered { struct simdjson_ondemand_unordered {
ondemand::parser parser{}; ondemand::parser parser{};
public:
bool run(const simdjson::padded_string &json, std::vector<point> &points) { bool run(const simdjson::padded_string &json, std::vector<point> &points) {
auto doc = parser.iterate(json); auto doc = parser.iterate(json);
for (ondemand::object coord : doc) { for (ondemand::object coord : doc) {

View File

@ -6,7 +6,7 @@
namespace large_random { namespace large_random {
class yyjson { struct yyjson {
simdjson_really_inline double get_double(yyjson_val *obj, std::string_view key) { simdjson_really_inline double get_double(yyjson_val *obj, std::string_view key) {
yyjson_val *val = yyjson_obj_getn(obj, key.data(), key.length()); yyjson_val *val = yyjson_obj_getn(obj, key.data(), key.length());
if (!val) { throw "missing point field!"; } if (!val) { throw "missing point field!"; }
@ -24,7 +24,6 @@ class yyjson {
} }
} }
public:
bool run(const simdjson::padded_string &json, std::vector<point> &points) { bool run(const simdjson::padded_string &json, std::vector<point> &points) {
// Walk the document, parsing the tweets as we go // Walk the document, parsing the tweets as we go
yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0); yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0);

View File

@ -8,8 +8,7 @@ namespace partial_tweets {
using namespace rapidjson; using namespace rapidjson;
template<int F> struct rapidjson_base {
class rapidjson_base {
Document doc{}; Document doc{};
simdjson_really_inline std::string_view get_string_view(Value &object, std::string_view key) { simdjson_really_inline std::string_view get_string_view(Value &object, std::string_view key) {
@ -39,9 +38,7 @@ class rapidjson_base {
return { get_uint64(field->value, "id"), get_string_view(field->value, "screen_name") }; return { get_uint64(field->value, "id"), get_string_view(field->value, "screen_name") };
} }
public: bool run(Document &root, std::vector<tweet> &tweets) {
bool run(const padded_string &json, std::vector<tweet> &tweets) {
auto &root = doc.Parse<F>(json.data());
if (root.HasParseError() || !root.IsObject()) { return false; } if (root.HasParseError() || !root.IsObject()) { return false; }
auto statuses = root.FindMember("statuses"); auto statuses = root.FindMember("statuses");
if (statuses == root.MemberEnd() || !statuses->value.IsArray()) { return false; } if (statuses == root.MemberEnd() || !statuses->value.IsArray()) { return false; }
@ -62,8 +59,13 @@ public:
} }
}; };
class rapidjson : public rapidjson_base<kParseValidateEncodingFlag> {}; struct rapidjson : public rapidjson_base {
BENCHMARK_TEMPLATE(partial_tweets, rapidjson); bool run(const padded_string &json, std::vector<tweet> &tweets) {
return rapidjson_base::run(doc.Parse<kParseValidateEncodingFlag>(json.data()), tweets);
}
};
BENCHMARK_TEMPLATE(partial_tweets, rapidjson);
} // namespace partial_tweets } // namespace partial_tweets

View File

@ -8,7 +8,7 @@ namespace partial_tweets {
using namespace simdjson; using namespace simdjson;
class simdjson_dom { struct simdjson_dom {
dom::parser parser{}; dom::parser parser{};
simdjson_really_inline uint64_t nullable_int(dom::element element) { simdjson_really_inline uint64_t nullable_int(dom::element element) {
@ -16,7 +16,6 @@ class simdjson_dom {
return element; return element;
} }
public:
bool run(const padded_string &json, std::vector<tweet> &tweets) { bool run(const padded_string &json, std::vector<tweet> &tweets) {
for (dom::element tweet : parser.parse(json)["statuses"]) { for (dom::element tweet : parser.parse(json)["statuses"]) {
auto user = tweet["user"]; auto user = tweet["user"];

View File

@ -9,7 +9,7 @@ namespace partial_tweets {
using namespace simdjson; using namespace simdjson;
using namespace simdjson::builtin; using namespace simdjson::builtin;
class simdjson_ondemand { struct simdjson_ondemand {
ondemand::parser parser{}; ondemand::parser parser{};
simdjson_really_inline uint64_t nullable_int(ondemand::value value) { simdjson_really_inline uint64_t nullable_int(ondemand::value value) {
@ -21,7 +21,6 @@ class simdjson_ondemand {
return { user.find_field("id"), user.find_field("screen_name") }; return { user.find_field("id"), user.find_field("screen_name") };
} }
public:
bool run(const padded_string &json, std::vector<tweet> &tweets) { bool run(const padded_string &json, std::vector<tweet> &tweets) {
// Walk the document, parsing the tweets as we go // Walk the document, parsing the tweets as we go
auto doc = parser.iterate(json); auto doc = parser.iterate(json);

View File

@ -6,7 +6,7 @@
namespace partial_tweets { namespace partial_tweets {
class yyjson { struct yyjson {
simdjson_really_inline std::string_view get_string_view(yyjson_val *obj, std::string_view key) { simdjson_really_inline std::string_view get_string_view(yyjson_val *obj, std::string_view key) {
auto val = yyjson_obj_getn(obj, key.data(), key.length()); auto val = yyjson_obj_getn(obj, key.data(), key.length());
if (!yyjson_is_str(val)) { throw "field is not uint64 or null!"; } if (!yyjson_is_str(val)) { throw "field is not uint64 or null!"; }
@ -30,7 +30,6 @@ class yyjson {
return { get_uint64(user, "id"), get_string_view(user, "screen_name") }; return { get_uint64(user, "id"), get_string_view(user, "screen_name") };
} }
public:
bool run(const padded_string &json, std::vector<tweet> &tweets) { bool run(const padded_string &json, std::vector<tweet> &tweets) {
// Walk the document, parsing the tweets as we go // Walk the document, parsing the tweets as we go
yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0); yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0);