From 62d620e2abaedbb28996670ec8d1627fd10dc1e1 Mon Sep 17 00:00:00 2001 From: Yiheng Wu <36156959+jingkaimori@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:45:31 +0800 Subject: [PATCH] [8_11] optimize performance of as_hexadecimal --- bench/lolly/data/numeral_bench.cpp | 2 +- lolly/data/numeral.cpp | 62 +++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/bench/lolly/data/numeral_bench.cpp b/bench/lolly/data/numeral_bench.cpp index 09ff71be..c6a33a4b 100644 --- a/bench/lolly/data/numeral_bench.cpp +++ b/bench/lolly/data/numeral_bench.cpp @@ -31,7 +31,7 @@ main () { bench.complexityN (d); bench.run ("convert hexadecimal string to int", [&] { from_hex (hex_string); }); - int hex_number= (0x1 << (d + 1)) - 1; + int hex_number= (0x1 << ((d + 1) * 4)) - 1; bench.run ("convert signed int to hexadecimal string", [&] { to_Hex (hex_number); }); bench.run ("convert unsigned int to hexadecimal string", diff --git a/lolly/data/numeral.cpp b/lolly/data/numeral.cpp index d50fd59b..38a8eaf6 100644 --- a/lolly/data/numeral.cpp +++ b/lolly/data/numeral.cpp @@ -233,12 +233,12 @@ from_hex (string s) { * to the tail. * @tparam T unsigned integral type is expected. */ -template +template std::enable_if_t, std::is_unsigned>, void> -as_hexadecimal_sub (T i, unsigned int cur, string& s) { - if (cur > 0) { - as_hexadecimal_sub (i >> 4, cur - 1, s); +as_hexadecimal_sub (T i, string& s) { + if constexpr (cur > 0) { + as_hexadecimal_sub (i >> 4, s); } s[cur]= hex_string[i & 15]; } @@ -246,7 +246,59 @@ as_hexadecimal_sub (T i, unsigned int cur, string& s) { string as_hexadecimal (int i, int len) { string result (len); - as_hexadecimal_sub ((unsigned) i, len - 1, result); + switch (len) { + case 1: + as_hexadecimal_sub<0> ((unsigned int) i, result); + break; + case 2: + as_hexadecimal_sub<1> ((unsigned int) i, result); + break; + case 3: + as_hexadecimal_sub<2> ((unsigned int) i, result); + break; + case 4: + as_hexadecimal_sub<3> ((unsigned int) i, result); + break; + case 5: + as_hexadecimal_sub<4> ((unsigned int) i, result); + break; + case 6: + as_hexadecimal_sub<5> ((unsigned int) i, result); + break; + case 7: + as_hexadecimal_sub<6> ((unsigned int) i, result); + break; + case 8: + as_hexadecimal_sub<7> ((unsigned int) i, result); + break; + case 9: + as_hexadecimal_sub<8> ((unsigned int) i, result); + break; + case 10: + as_hexadecimal_sub<9> ((unsigned int) i, result); + break; + case 11: + as_hexadecimal_sub<10> ((unsigned int) i, result); + break; + case 12: + as_hexadecimal_sub<11> ((unsigned int) i, result); + break; + case 13: + as_hexadecimal_sub<12> ((unsigned int) i, result); + break; + case 14: + as_hexadecimal_sub<13> ((unsigned int) i, result); + break; + case 15: + as_hexadecimal_sub<14> ((unsigned int) i, result); + break; + case 16: + as_hexadecimal_sub<15> ((unsigned int) i, result); + break; + default: + TM_FAILED ("len is too large"); + break; + } return result; }