Skip to content

Commit

Permalink
boost performance of api converting number to hexadecimal string
Browse files Browse the repository at this point in the history
  • Loading branch information
jingkaimori committed Jun 6, 2024
1 parent ad490cd commit 2e79bd8
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 7 deletions.
40 changes: 40 additions & 0 deletions bench/lolly/data/numeral_bench.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/** \file numeral_bench.cpp
* \copyright GPLv3
* \details Benchmark for converter between numeral and string
* \author jingkaimori
* \date 2024
*/

#include "lolly/data/numeral.hpp"
#include <nanobench.h>

using namespace lolly::data;

static ankerl::nanobench::Bench bench;

namespace lolly {
extern void init_tbox ();
} // namespace lolly

int
main () {
lolly::init_tbox ();
#ifdef OS_WASM
bench.minEpochIterations (2000);
#else
bench.minEpochIterations (400000);
#endif

string hex_string;
for (int d= 1; d < 6; d++) {
hex_string << ('a' + d % 6);
bench.complexityN (d);
bench.run ("convert hexadecimal string to int",
[&] { from_hex (hex_string); });
int hex_number = (0x1 << (d+1)) - 1;
bench.run ("convert signed int to hexadecimal string",
[&] { to_Hex (hex_number); });
bench.run ("convert unsigned int to hexadecimal string",
[&] { as_hexadecimal (hex_number, d); });
}
}
28 changes: 21 additions & 7 deletions lolly/data/numeral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,23 @@ to_padded_hex (uint8_t i) {
return locase_all (to_padded_Hex (i));
}

template <typename T>
std::enable_if_t<std::conjunction_v<std::is_integral<T>, std::is_unsigned<T>>,
string>
to_Hex_positive (T i) {
if (i < 16) return hex_string[i & 15];
return to_Hex_positive (i >> 4) << hex_string[i & 15];
}

string
to_Hex (int32_t i) {
if (i == INT32_MIN) return "-80000000";
if (i < 0) return "-" * to_Hex (-i);
if (i < 16) return hex_string[i & 15];
return to_Hex (i >> 4) * hex_string[i & 15];
if (i < 0) {
return string ("-") << to_Hex_positive ((uint32_t) (-i));
}
else {
return to_Hex_positive ((uint32_t) i);
};
}

string
Expand All @@ -170,9 +181,12 @@ to_hex (int32_t i) {
string
to_Hex (pointer ptr) {
intptr_t i= (intptr_t) ptr;
if (i < 0) return "-" * to_Hex (-i);
if (i < 16) return hex_string[i & 15];
return to_Hex (i >> 4) * hex_string[i & 15];
if (i < 0) {
return string ("-") << to_Hex_positive ((uintptr_t) (-i));
}
else {
return to_Hex_positive ((uintptr_t) i);
};
}

string
Expand All @@ -196,7 +210,7 @@ from_hex (string s) {
string
as_hexadecimal (int i, int len) {
if (len == 1) return hex_string[i & 15];
else return as_hexadecimal (i >> 4, len - 1) * hex_string[i & 15];
else return as_hexadecimal (i >> 4, len - 1) << hex_string[i & 15];
}

} // namespace data
Expand Down
19 changes: 19 additions & 0 deletions tests/lolly/data/numeral_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,22 @@ TEST_CASE ("to_hex/to_Hex") {
string_eq (to_hex (INT32_MAX + 1), "-80000000");
}
}

TEST_CASE ("as_hexadecimal") {
SUBCASE ("0-15 (+/-)") {
for (int i= 1; i < 10; i++) {
string_eq (as_hexadecimal (i, 1), as_string (i));
string_eq (as_hexadecimal (i, 1), as_string (i));
}
string_eq (as_hexadecimal (0, 1), "0");
string_eq (as_hexadecimal (10, 1), "A");
string_eq (as_hexadecimal (11, 1), "B");
string_eq (as_hexadecimal (12, 1), "C");
string_eq (as_hexadecimal (13, 1), "D");
string_eq (as_hexadecimal (14, 1), "E");
string_eq (as_hexadecimal (15, 1), "F");
string_eq (as_hexadecimal (0x12, 2), "12");
string_eq (as_hexadecimal (0xABC, 3), "ABC");
}
SUBCASE ("max") { string_eq (as_hexadecimal (UINT32_MAX, 8), "FFFFFFFF"); }
}

0 comments on commit 2e79bd8

Please sign in to comment.