diff options
author | Bruno Lima <bdl1998@hotmail.com> | 2024-07-14 09:05:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-14 09:05:35 (GMT) |
commit | 04130b290b545e64625c07dc8fa2709d17e70880 (patch) | |
tree | 1d748d0be64a86c777a02e46188c3606c1ca9953 | |
parent | f6f4022a357f70f1c40945403065e81b6c2e4854 (diff) | |
download | cpython-04130b290b545e64625c07dc8fa2709d17e70880.zip cpython-04130b290b545e64625c07dc8fa2709d17e70880.tar.gz cpython-04130b290b545e64625c07dc8fa2709d17e70880.tar.bz2 |
gh-121562: optimized hex_from_char (#121563)
Performance improvement to `float.fromhex`: use a lookup table
for computing the hexadecimal value of a character, in place of the
previous switch-case construct. Patch by Bruno Lima.
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2024-07-10-02-02-32.gh-issue-121562.8beIMi.rst | 2 | ||||
-rw-r--r-- | Objects/floatobject.c | 94 |
2 files changed, 34 insertions, 62 deletions
diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-10-02-02-32.gh-issue-121562.8beIMi.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-10-02-02-32.gh-issue-121562.8beIMi.rst new file mode 100644 index 0000000..9403809 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-07-10-02-02-32.gh-issue-121562.8beIMi.rst @@ -0,0 +1,2 @@ +Optimized performance of hex_from_char by replacing switch-case with a +lookup table diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 2627ba8..31f4145 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1142,69 +1142,39 @@ char_from_hex(int x) return Py_hexdigits[x]; } +/* This table maps characters to their hexadecimal values, only + * works with encodings whose lower half is ASCII (like UTF-8). + * '0' maps to 0, ..., '9' maps to 9. + * 'a' and 'A' map to 10, ..., 'f' and 'F' map to 15. + * All other indices map to -1. + */ +static const int +_CHAR_TO_HEX[256] = { + -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, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -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, 10, 11, 12, 13, 14, 15, -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, -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, +}; + +/* Convert a character to its hexadecimal value, or -1 if it's not a + * valid hexadecimal character, only works with encodings whose lower + * half is ASCII (like UTF-8). + */ static int -hex_from_char(char c) { - int x; - switch(c) { - case '0': - x = 0; - break; - case '1': - x = 1; - break; - case '2': - x = 2; - break; - case '3': - x = 3; - break; - case '4': - x = 4; - break; - case '5': - x = 5; - break; - case '6': - x = 6; - break; - case '7': - x = 7; - break; - case '8': - x = 8; - break; - case '9': - x = 9; - break; - case 'a': - case 'A': - x = 10; - break; - case 'b': - case 'B': - x = 11; - break; - case 'c': - case 'C': - x = 12; - break; - case 'd': - case 'D': - x = 13; - break; - case 'e': - case 'E': - x = 14; - break; - case 'f': - case 'F': - x = 15; - break; - default: - x = -1; - break; - } - return x; +hex_from_char(unsigned char c) { + return _CHAR_TO_HEX[c]; } /* convert a float to a hexadecimal string */ |