From f75fdbbbbe2c74dc02f08c0e9b9a06db8c1decfc Mon Sep 17 00:00:00 2001 From: Vitalii Demianets Date: Thu, 22 Aug 2013 16:02:02 +0200 Subject: [PATCH] Improve performance of work generation by optimizing hex2bin and bin2hex sprintf is a very expensive function, do direct translation instead. --- util.c | 50 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/util.c b/util.c index 032a82ca..d3d2897f 100644 --- a/util.c +++ b/util.c @@ -588,10 +588,13 @@ char *get_proxy(char *url, struct pool *pool) void __bin2hex(char *s, const unsigned char *p, size_t len) { int i; + static const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - for (i = 0; i < (int)len; i++) - sprintf(s + (i * 2), "%02x", (unsigned int)p[i]); - + for (i = 0; i < (int)len; i++) { + *s++ = hex[p[i] >> 4]; + *s++ = hex[p[i] & 0xF]; + } + *s++ = '\0'; } /* Returns a malloced array string of a binary value of arbitrary length. The @@ -615,33 +618,48 @@ char *bin2hex(const unsigned char *p, size_t len) } /* Does the reverse of bin2hex but does not allocate any ram */ +static const int hex2bin_tbl[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, +}; bool hex2bin(unsigned char *p, const char *hexstr, size_t len) { + int nibble1, nibble2; + unsigned char idx; bool ret = false; while (*hexstr && len) { - char hex_byte[4]; - unsigned int v; - if (unlikely(!hexstr[1])) { applog(LOG_ERR, "hex2bin str truncated"); return ret; } - memset(hex_byte, 0, 4); - hex_byte[0] = hexstr[0]; - hex_byte[1] = hexstr[1]; + idx = *hexstr++; + nibble1 = hex2bin_tbl[idx]; + idx = *hexstr++; + nibble2 = hex2bin_tbl[idx]; - if (unlikely(sscanf(hex_byte, "%x", &v) != 1)) { - applog(LOG_INFO, "hex2bin sscanf '%s' failed", hex_byte); + if (unlikely((nibble1 < 0) || (nibble2 < 0))) { + applog(LOG_ERR, "hex2bin scan failed"); return ret; } - *p = (unsigned char) v; - - p++; - hexstr += 2; - len--; + *p++ = (((unsigned char)nibble1) << 4) | ((unsigned char)nibble2); + --len; } if (likely(len == 0 && *hexstr == 0))