One of our developers just did a hex string to int conversion with array_sscanf(x, "%x")[0]. Since we have int2hex, string2hex and hex2string I thought it would be symmetric to add a hex2int function as well. However doing it with
/*! @decl int hex2int(string hex) *! @appears String.hex2int *! *! Convert a string of hexadecimal digits to an integer. *! *! @seealso *! @[int2hex()] */ PMOD_EXPORT PIKEFUN int hex2int(string hex) errname String.hex2int; optflags OPT_TRY_OPTIMIZE; { int r=0; unsigned char *q = (unsigned char *)hex->str; int len = hex->len; if(hex->size_shift) Pike_error("Only hex digits allowed.\n");
for (; len; len--) { r <<= 4; r |= hexdecode[*q++]; } RETURN r; }
was about twice as slow as the array_sscanf approach. Is that because some special sscanf handling?
Yes, but wasn't sscanf the fast code?
Anyway, if you want to try something exotic, you can try:
int low_hex2int(int c) { int q = c & 0x40; return (c + (q>>3) + (q>>6)) & 0xf; }
I presume the lookup table code comes from the hex2string/string2hex code.
I added it there because it significantly speed up operations with long strings, while keeping compatibility (your shift solution would probably be faster, though).
The reason it works well there is because the strings in question is usually long enough to hide the lookup table version memory access latency.
pike-devel@lists.lysator.liu.se