Skip to content

Commit

Permalink
Testing with function ptrs.
Browse files Browse the repository at this point in the history
  • Loading branch information
RealTimeChris committed Jan 4, 2025
1 parent da8ab2e commit 434e3b7
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 165 deletions.
46 changes: 46 additions & 0 deletions Benchmarks/Tests.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,52 @@ namespace tests {

template<json_library lib, test_type type, typename test_data_type, bool minified, size_t iterations, const bnch_swt::string_literal testName> struct json_test_helper;

template<typename value_type> struct parse_raw_json_data {};

template<> struct parse_raw_json_data<test_struct> {
test_struct impl(jsonifier::raw_json_data& rawJsonData) {
test_struct output{};
if (rawJsonData.getType() == jsonifier::json_type::object) {
auto& json_object = rawJsonData.getObject();
for (auto& [key, value]: json_object) {
if (key == "testVals01" && value.getType() == jsonifier::json_type::array) {
for (auto& element: value.getArray()) {
if (element.getType() == jsonifier::json_type::string) {
output.testVals01.emplace_back(static_cast<std::string>(element.getString()));
}
}
} else if (key == "testVals02" && value.getType() == jsonifier::json_type::array) {
for (auto& element: value.getArray()) {
if (element.getType() == jsonifier::json_type::number) {
output.testVals02.emplace_back(element.getUint());
}
}
} else if (key == "testVals03" && value.getType() == jsonifier::json_type::array) {
for (auto& element: value.getArray()) {
if (element.getType() == jsonifier::json_type::number) {
output.testVals03.emplace_back(element.getInt());
}
}
} else if (key == "testVals04" && value.getType() == jsonifier::json_type::array) {
for (auto& element: value.getArray()) {
if (element.getType() == jsonifier::json_type::number) {
output.testVals04.emplace_back(element.getDouble());
}
}
} else if (key == "testVals05" && value.getType() == jsonifier::json_type::array) {
for (auto& element: value.getArray()) {
if (element.getType() == jsonifier::json_type::boolean) {
output.testVals05.emplace_back(element.getBool());
}
}
}
}
}
return output;
}

};

template<typename test_data_type, bool minified, size_t iterations, const bnch_swt::string_literal testNameNew>
struct json_test_helper<json_library::jsonifier, test_type::parse_and_serialize_raw_json_data, test_data_type, minified, iterations, testNameNew> {
static auto run(std::string& newBuffer) {
Expand Down
181 changes: 31 additions & 150 deletions Include/jsonifier/IToStr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,34 +53,29 @@ namespace jsonifier_internal {
return (x + digitCountTable[31 - simd_internal::lzcnt(x | 1)]) >> 32;
}

template<typename value_type> JSONIFIER_INLINE static char* toCharsByDigitCountUint32Max(char* buf, value_type value) noexcept {
uint64_t numDigits{ fastDigitCount(static_cast<uint32_t>(value)) };
uint32_t aa, bb, cc, dd, aabb, bbcc, ccdd, ee, ddee;
uint64_t aabbcc;
switch (numDigits) {
case 1: {
struct integer_serializer {
template<size_t index> static char* impl(char* buf, uint64_t value) noexcept {
uint32_t aa, bb, cc, dd, aabb, bbcc, ccdd, ee, ddee;
uint64_t aabbcc;
if constexpr (index == 1) {
std::memcpy(buf, charTable1 + value, 1);
return buf + 1;
}
case 2: {
} else if constexpr (index == 2) {
std::memcpy(buf, charTable2 + value * 2, 2);
return buf + 2;
}
case 3: {
} else if constexpr (index == 3) {
aa = (value * 5243) >> 19;
bb = value - aa * 100;
std::memcpy(buf, charTable1 + aa, 1);
std::memcpy(buf + 1, charTable2 + bb * 2, 2);
return buf + 3;
}
case 4: {
} else if constexpr (index == 4) {
aa = (value * 5243) >> 19;
bb = value - aa * 100;
std::memcpy(buf, charTable2 + aa * 2, 2);
std::memcpy(buf + 2, charTable2 + bb * 2, 2);
return buf + 4;
}
case 5: {
} else if constexpr (index == 5) {
aa = (value * 429497) >> 32;
bbcc = value - aa * 10000;
bb = (bbcc * 5243) >> 19;
Expand All @@ -89,8 +84,7 @@ namespace jsonifier_internal {
std::memcpy(buf + 1, charTable2 + bb * 2, 2);
std::memcpy(buf + 3, charTable2 + cc * 2, 2);
return buf + 5;
}
case 6: {
} else if constexpr (index == 6) {
aa = (value * 429497) >> 32;
bbcc = value - aa * 10000;
bb = (bbcc * 5243) >> 19;
Expand All @@ -99,8 +93,7 @@ namespace jsonifier_internal {
std::memcpy(buf + 2, charTable2 + bb * 2, 2);
std::memcpy(buf + 4, charTable2 + cc * 2, 2);
return buf + 6;
}
case 7: {
} else if constexpr (index == 7) {
aabb = (value * 109951163) >> 40;
ccdd = value - aabb * 10000;
aa = (aabb * 5243) >> 19;
Expand All @@ -112,8 +105,7 @@ namespace jsonifier_internal {
std::memcpy(buf + 3, charTable2 + cc * 2, 2);
std::memcpy(buf + 5, charTable2 + dd * 2, 2);
return buf + 7;
}
case 8: {
} else if constexpr (index == 8) {
aabb = (value * 109951163) >> 40;
ccdd = value - aabb * 10000;
aa = (aabb * 5243) >> 19;
Expand All @@ -125,8 +117,7 @@ namespace jsonifier_internal {
std::memcpy(buf + 4, charTable2 + cc * 2, 2);
std::memcpy(buf + 6, charTable2 + dd * 2, 2);
return buf + 8;
}
case 9: {
} else if constexpr (index == 9) {
aabbcc = (value * 3518437209ul) >> 45;
aa = (aabbcc * 429497) >> 32;
ddee = value - aabbcc * 10000;
Expand All @@ -141,8 +132,7 @@ namespace jsonifier_internal {
std::memcpy(buf + 5, charTable2 + dd * 2, 2);
std::memcpy(buf + 7, charTable2 + ee * 2, 2);
return buf + 9;
}
case 10: {
} else if constexpr (index == 10) {
aabbcc = (value * 3518437209ul) >> 45;
aa = (aabbcc * 429497) >> 32;
ddee = value - aabbcc * 10000;
Expand All @@ -157,145 +147,36 @@ namespace jsonifier_internal {
std::memcpy(buf + 6, charTable2 + dd * 2, 2);
std::memcpy(buf + 8, charTable2 + ee * 2, 2);
return buf + 10;
}
default: {
} else {
return buf;
}
}
};

template<size_t... indices> static constexpr auto generateFunctionPtrs(std::index_sequence<indices...>) noexcept {
using function_type = decltype(&integer_serializer::impl<0>);
return array<function_type, sizeof...(indices)>{ { integer_serializer::impl<indices> }... };
}

static constexpr auto functionPtrsSerialize{ generateFunctionPtrs(std::make_index_sequence<11>{}) };

template<typename value_type> JSONIFIER_INLINE static char* toCharsByDigitCountUint32Max(char* buf, value_type value) noexcept {
uint64_t numDigits{ fastDigitCount(static_cast<uint32_t>(value)) };
uint32_t aa, bb, cc, dd, aabb, bbcc, ccdd, ee, ddee;
uint64_t aabbcc;
return functionPtrsSerialize[numDigits](buf, value);
}

template<typename value_type> JSONIFIER_INLINE static char* toCharsByDigitCount1_8(char* buf, value_type value) noexcept {
uint64_t numDigits{ fastDigitCount(static_cast<uint32_t>(value)) };
uint64_t aa, bb, cc, dd, aabb, bbcc, ccdd;
switch (numDigits) {
case 1: {
std::memcpy(buf, charTable1 + value, 1);
return buf + 1;
}
case 2: {
std::memcpy(buf, charTable2 + value * 2, 2);
return buf + 2;
}
case 3: {
aa = (value * 5243) >> 19;
bb = value - aa * 100;
std::memcpy(buf, charTable1 + aa, 1);
std::memcpy(buf + 1, charTable2 + bb * 2, 2);
return buf + 3;
}
case 4: {
aa = (value * 5243) >> 19;
bb = value - aa * 100;
std::memcpy(buf, charTable2 + aa * 2, 2);
std::memcpy(buf + 2, charTable2 + bb * 2, 2);
return buf + 4;
}
case 5: {
aa = (value * 429497) >> 32;
bbcc = value - aa * 10000;
bb = (bbcc * 5243) >> 19;
cc = bbcc - bb * 100;
std::memcpy(buf, charTable1 + aa, 1);
std::memcpy(buf + 1, charTable2 + bb * 2, 2);
std::memcpy(buf + 3, charTable2 + cc * 2, 2);
return buf + 5;
}
case 6: {
aa = (value * 429497) >> 32;
bbcc = value - aa * 10000;
bb = (bbcc * 5243) >> 19;
cc = bbcc - bb * 100;
std::memcpy(buf, charTable2 + aa * 2, 2);
std::memcpy(buf + 2, charTable2 + bb * 2, 2);
std::memcpy(buf + 4, charTable2 + cc * 2, 2);
return buf + 6;
}
case 7: {
aabb = (value * 109951163) >> 40;
ccdd = value - aabb * 10000;
aa = (aabb * 5243) >> 19;
cc = (ccdd * 5243) >> 19;
bb = aabb - aa * 100;
dd = ccdd - cc * 100;
std::memcpy(buf + 0, charTable1 + aa, 1);
std::memcpy(buf + 1, charTable2 + bb * 2, 2);
std::memcpy(buf + 3, charTable2 + cc * 2, 2);
std::memcpy(buf + 5, charTable2 + dd * 2, 2);
return buf + 7;
}
case 8: {
aabb = (value * 109951163) >> 40;
ccdd = value - aabb * 10000;
aa = (aabb * 5243) >> 19;
cc = (ccdd * 5243) >> 19;
bb = aabb - aa * 100;
dd = ccdd - cc * 100;
std::memcpy(buf, charTable2 + aa * 2, 2);
std::memcpy(buf + 2, charTable2 + bb * 2, 2);
std::memcpy(buf + 4, charTable2 + cc * 2, 2);
std::memcpy(buf + 6, charTable2 + dd * 2, 2);
return buf + 8;
}
default: {
return buf;
}
}
return functionPtrsSerialize[numDigits](buf, value);
}

template<typename value_type> JSONIFIER_INLINE static char* toCharsByDigitCount5_8(char* buf, value_type value) noexcept {
uint32_t numDigits{ fastDigitCount(static_cast<uint32_t>(value)) };
uint32_t aa, bb, cc, dd, aabb, bbcc, ccdd;
switch (numDigits) {
case 5: {
aa = (value * 429497) >> 32;
bbcc = value - aa * 10000;
bb = (bbcc * 5243) >> 19;
cc = bbcc - bb * 100;
std::memcpy(buf, charTable1 + aa, 1);
std::memcpy(buf + 1, charTable2 + bb * 2, 2);
std::memcpy(buf + 3, charTable2 + cc * 2, 2);
return buf + 5;
}
case 6: {
aa = (value * 429497) >> 32;
bbcc = value - aa * 10000;
bb = (bbcc * 5243) >> 19;
cc = bbcc - bb * 100;
std::memcpy(buf, charTable2 + aa * 2, 2);
std::memcpy(buf + 2, charTable2 + bb * 2, 2);
std::memcpy(buf + 4, charTable2 + cc * 2, 2);
return buf + 6;
}
case 7: {
aabb = (value * 109951163) >> 40;
ccdd = value - aabb * 10000;
aa = (aabb * 5243) >> 19;
cc = (ccdd * 5243) >> 19;
bb = aabb - aa * 100;
dd = ccdd - cc * 100;
std::memcpy(buf + 0, charTable1 + aa, 1);
std::memcpy(buf + 1, charTable2 + bb * 2, 2);
std::memcpy(buf + 3, charTable2 + cc * 2, 2);
std::memcpy(buf + 5, charTable2 + dd * 2, 2);
return buf + 7;
}
case 8: {
aabb = (value * 109951163) >> 40;
ccdd = value - aabb * 10000;
aa = (aabb * 5243) >> 19;
cc = (ccdd * 5243) >> 19;
bb = aabb - aa * 100;
dd = ccdd - cc * 100;
std::memcpy(buf, charTable2 + aa * 2, 2);
std::memcpy(buf + 2, charTable2 + bb * 2, 2);
std::memcpy(buf + 4, charTable2 + cc * 2, 2);
std::memcpy(buf + 6, charTable2 + dd * 2, 2);
return buf + 8;
}
default: {
return buf;
}
}
return functionPtrsSerialize[numDigits](buf, value);
}

template<jsonifier::concepts::uns64_t value_type> JSONIFIER_INLINE static char* toChars(char* buf, value_type value) noexcept {
Expand Down
54 changes: 39 additions & 15 deletions Include/jsonifier/RawJsonData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ namespace jsonifier {

json_number(const string& stringNew) noexcept : rawJson{ stringNew } {};

uint64_t getUint() {
uint64_t getUint() const {
return strToUint64(rawJson);
}

int64_t getInt() {
int64_t getInt() const {
return strToInt64(rawJson);
}

double getDouble() {
double getDouble() const {
return strToDouble(rawJson);
}

Expand Down Expand Up @@ -107,32 +107,56 @@ namespace jsonifier {
}
}

[[nodiscard]] bool& getBool() noexcept {
return *std::get<std::unique_ptr<bool>>(value);
[[nodiscard]] const object_type& getObject() const noexcept {
return *std::get<std::unique_ptr<object_type>>(value);
}

[[nodiscard]] double getDouble() noexcept {
return std::get<std::unique_ptr<number_type>>(value)->getDouble();
[[nodiscard]] object_type& getObject() noexcept {
return *std::get<std::unique_ptr<object_type>>(value);
}

[[nodiscard]] int64_t getInt() noexcept {
return std::get<std::unique_ptr<number_type>>(value)->getInt();
[[nodiscard]] const array_type& getArray() const noexcept {
return *std::get<std::unique_ptr<array_type>>(value);
}

[[nodiscard]] array_type& getArray() noexcept {
return *std::get<std::unique_ptr<array_type>>(value);
}

[[nodiscard]] uint64_t getUint() noexcept {
return std::get<std::unique_ptr<number_type>>(value)->getUint();
[[nodiscard]] const string& getString() const noexcept {
return *std::get<std::unique_ptr<string>>(value);
}

[[nodiscard]] string& getString() noexcept {
return *std::get<std::unique_ptr<string>>(value);
}

[[nodiscard]] object_type& getObject() noexcept {
return *std::get<std::unique_ptr<object_type>>(value);
[[nodiscard]] const number_type& getNumber() const noexcept {
return *std::get<std::unique_ptr<number_type>>(value);
}

[[nodiscard]] array_type& getArray() noexcept {
return *std::get<std::unique_ptr<array_type>>(value);
[[nodiscard]] number_type& getNumber() noexcept {
return *std::get<std::unique_ptr<number_type>>(value);
}

[[nodiscard]] double getDouble() const noexcept {
return std::get<std::unique_ptr<number_type>>(value)->getDouble();
}

[[nodiscard]] int64_t getInt() const noexcept {
return std::get<std::unique_ptr<number_type>>(value)->getInt();
}

[[nodiscard]] uint64_t getUint() const noexcept {
return std::get<std::unique_ptr<number_type>>(value)->getUint();
}

[[nodiscard]] const bool_type& getBool() const noexcept {
return *std::get<std::unique_ptr<bool_type>>(value);
}

[[nodiscard]] bool_type& getBool() noexcept {
return *std::get<std::unique_ptr<bool_type>>(value);
}

template<std::integral index_type> raw_json_data& operator[](index_type&& index) noexcept {
Expand Down

0 comments on commit 434e3b7

Please sign in to comment.