Browse Source

update: perf CommonCode string decoding

master
Dnomd343 1 week 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(CommonCodeDeserialize)->Range(8, 256);
BENCHMARK(CommonCodeDeserialize)->Range(8, 256);
// BENCHMARK(CommonCodeSerializeShorten)->Range(8, 256);
// BENCHMARK(CommonCodeDeserializeShorten)->Range(8, 256);
// BENCHMARK(ShortCodeSerialize)->Range(8, 256);
// BENCHMARK(ShortCodeDeserialize)->Range(8, 256);
BENCHMARK(IsMirrorCompare);
// BENCHMARK(IsMirrorCompare);
// BENCHMARK(ShortCodeToCommonCode);
// 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.
static char to_hex_char(const uint64_t hex_bit) {
[[assume(hex_bit < 0x10)]];
KLSK_ASSUME(hex_bit < 0x10);
if (hex_bit < 0xA) {
return static_cast<char>(hex_bit + '0');
}
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) {
char code_str[9];
for (int i = 0; i < 9; ++i) {
@ -29,25 +71,19 @@ std::string CommonCode::string_encode_shorten(const uint64_t common_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) {
if (common_code.length() > 9 || common_code.empty()) {
return std::nullopt; // invalid string length
}
uint64_t result = 0;
for (const auto hex_bit : common_code) {
if (hex_bit >= '0' && hex_bit <= '9') { // 0 ~ 9
(result <<= 4) |= (hex_bit - '0');
} else if (hex_bit >= 'A' && hex_bit <= 'F') { // A ~ F
(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
uint64_t code = 0;
for (const uint8_t hex_bit : common_code) {
const auto val = CONVERT_TABLE[hex_bit]; // table convert
if (val == -1) {
return std::nullopt;
}
(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

Loading…
Cancel
Save