Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hex_from_char run faster replacing switch-case with lookup table #121562

Closed
LimaBD opened this issue Jul 10, 2024 · 2 comments
Closed

hex_from_char run faster replacing switch-case with lookup table #121562

LimaBD opened this issue Jul 10, 2024 · 2 comments
Labels
performance Performance or resource usage type-feature A feature request or enhancement

Comments

@LimaBD
Copy link
Contributor

LimaBD commented Jul 10, 2024

Feature or enhancement

Proposal:

Replacing switch-case in hex_from_char with a lookup table makes python float.fromhex(...) run 4%-5% faster. Probably if we measure hex_from_char in isolation we will get a much greater % improvement.

cpython/Objects/floatobject.c

Lines 1145 to 1208 in f621618

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;
}

New hex_from_char code:

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,
};

static int
hex_from_char(unsigned char c) {
    return _char_to_hex[c];
}

Timing with old hex_from_char:

$ ./python -m pyperf timeit --duplicate 100 "float.fromhex('0x123456.ffffp10')"
.....................
Mean +- std dev: 86.0 ns +- 0.9 ns

With new hex_from_char:

./python -m pyperf timeit --duplicate 100 "float.fromhex('0x123456.ffffp10')"
.....................
Mean +- std dev: 81.8 ns +- 1.0 ns

I will create a new PR.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Linked PRs

@LimaBD LimaBD added the type-feature A feature request or enhancement label Jul 10, 2024
@Eclips4 Eclips4 added the performance Performance or resource usage label Jul 10, 2024
LimaBD added a commit to LimaBD/cpython that referenced this issue Jul 10, 2024
LimaBD added a commit to LimaBD/cpython that referenced this issue Jul 10, 2024
@serhiy-storchaka
Copy link
Member

@mdickinson, this code was added by you in 65fe25e (bpo-3008/gh-47258).

LimaBD added a commit to LimaBD/cpython that referenced this issue Jul 10, 2024
mdickinson pushed a commit that referenced this issue Jul 14, 2024
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.
@LimaBD
Copy link
Contributor Author

LimaBD commented Jul 14, 2024

PR merged!

@LimaBD LimaBD closed this as completed Jul 14, 2024
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Performance or resource usage type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants