Browse Source

update: perf CommonCode string decoding

master
Dnomd343 3 months ago
parent
commit
33ed2178dc
  1. 4
      src/core/benchmark/codec.cc
  2. 64
      src/core/common_code/internal/serialize.cc

4
src/core/benchmark/codec.cc

@ -261,14 +261,14 @@ static void IsMirrorCompare(benchmark::State &state) {
} }
// BENCHMARK(CommonCodeSerialize)->Range(8, 256); // BENCHMARK(CommonCodeSerialize)->Range(8, 256);
// BENCHMARK(CommonCodeDeserialize)->Range(8, 256); BENCHMARK(CommonCodeDeserialize)->Range(8, 256);
// BENCHMARK(CommonCodeSerializeShorten)->Range(8, 256); // BENCHMARK(CommonCodeSerializeShorten)->Range(8, 256);
// BENCHMARK(CommonCodeDeserializeShorten)->Range(8, 256); // BENCHMARK(CommonCodeDeserializeShorten)->Range(8, 256);
// BENCHMARK(ShortCodeSerialize)->Range(8, 256); // BENCHMARK(ShortCodeSerialize)->Range(8, 256);
// BENCHMARK(ShortCodeDeserialize)->Range(8, 256); // BENCHMARK(ShortCodeDeserialize)->Range(8, 256);
BENCHMARK(IsMirrorCompare); // BENCHMARK(IsMirrorCompare);
// BENCHMARK(ShortCodeToCommonCode); // BENCHMARK(ShortCodeToCommonCode);
// BENCHMARK(CommonCodeToShortCode); // BENCHMARK(CommonCodeToShortCode);

64
src/core/common_code/internal/serialize.cc

@ -4,13 +4,55 @@ namespace klotski::codec {
/// Convert a single hexadecimal digit to a character. /// Convert a single hexadecimal digit to a character.
static char to_hex_char(const uint64_t hex_bit) { static char to_hex_char(const uint64_t hex_bit) {
[[assume(hex_bit < 0x10)]]; KLSK_ASSUME(hex_bit < 0x10);
if (hex_bit < 0xA) { if (hex_bit < 0xA) {
return static_cast<char>(hex_bit + '0'); return static_cast<char>(hex_bit + '0');
} }
return static_cast<char>(hex_bit + 'A' - 10); return static_cast<char>(hex_bit + 'A' - 10);
} }
constexpr auto CONVERT_TABLE = std::to_array<char>({
/// -1 * 48
-1, -1, -1, -1, -1, -1, // [0, 5]
-1, -1, -1, -1, -1, -1, -1, // [6, 12]
-1, -1, -1, -1, -1, -1, -1, // [13, 19]
-1, -1, -1, -1, -1, -1, -1, // [20, 26]
-1, -1, -1, -1, -1, -1, -1, // [27, 33]
-1, -1, -1, -1, -1, -1, -1, // [34, 40]
-1, -1, -1, -1, -1, -1, -1, // [41, 47]
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // [48, 57]
/// -1 * 7
-1, -1, -1, -1, -1, -1, -1, // [58, 64]
10, 11, 12, 13, 14, 15, // [65, 70]
/// -1 * 26
-1, -1, -1, -1, -1, -1, -1, // [71, 77]
-1, -1, -1, -1, -1, -1, -1, // [78, 84]
-1, -1, -1, -1, -1, -1, -1, // [85, 91]
-1, -1, -1, -1, -1, // [92, 96]
10, 11, 12, 13, 14, 15, // [97, 102]
/// -1 * 25
-1, -1, -1, -1, -1, -1, -1, // [103, 109]
-1, -1, -1, -1, -1, -1, -1, // [110, 116]
-1, -1, -1, -1, -1, -1, -1, // [117, 123]
-1, -1, -1, -1, // [124, 127]
/// -1 * 128
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
});
std::string CommonCode::string_encode(uint64_t common_code) { std::string CommonCode::string_encode(uint64_t common_code) {
char code_str[9]; char code_str[9];
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
@ -29,25 +71,19 @@ std::string CommonCode::string_encode_shorten(const uint64_t common_code) {
return code; return code;
} }
// TODO: direct table lookup can bring about a 30% improvement,
// TODO: but it is necessary to confirm the performance of different CPU caches.
std::optional<uint64_t> CommonCode::string_decode(const std::string_view common_code) { std::optional<uint64_t> CommonCode::string_decode(const std::string_view common_code) {
if (common_code.length() > 9 || common_code.empty()) { if (common_code.length() > 9 || common_code.empty()) {
return std::nullopt; // invalid string length return std::nullopt; // invalid string length
} }
uint64_t result = 0; uint64_t code = 0;
for (const auto hex_bit : common_code) { for (const uint8_t hex_bit : common_code) {
if (hex_bit >= '0' && hex_bit <= '9') { // 0 ~ 9 const auto val = CONVERT_TABLE[hex_bit]; // table convert
(result <<= 4) |= (hex_bit - '0'); if (val == -1) {
} else if (hex_bit >= 'A' && hex_bit <= 'F') { // A ~ F return std::nullopt;
(result <<= 4) |= (hex_bit - 'A' + 10);
} else if (hex_bit >= 'a' && hex_bit <= 'f') { // a ~ f
(result <<= 4) |= (hex_bit - 'a' + 10);
} else {
return std::nullopt; // invalid character
} }
(code <<= 4) |= val;
} }
return result << (36 - common_code.length() * 4); // low-bits fill with zero return code << (36 - common_code.length() * 4); // low-bits fill with zero
} }
} // namespace klotski::codec } // namespace klotski::codec

Loading…
Cancel
Save