Improve performance of work generation by optimizing hex2bin and bin2hex sprintf is a very expensive function, do direct translation instead.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
diff --git a/util.c b/util.c
index 032a82c..d3d2897 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))