Skip to content

Commit

Permalink
bpo-40313: speed up bytes.hex() (GH-19594)
Browse files Browse the repository at this point in the history
Automerge-Triggered-By: @gpshead
  • Loading branch information
sweeneyde committed Apr 21, 2020
1 parent bba760e commit 6a9e80a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 12 deletions.
@@ -0,0 +1 @@
Improve the performance of bytes.hex().
61 changes: 49 additions & 12 deletions Python/pystrhex.c
Expand Up @@ -82,22 +82,59 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen,

/* Hexlify */
Py_ssize_t i, j;
for (i=j=0; i < arglen; ++i) {
assert((j + 1) < resultlen);
unsigned char c;
c = (argbuf[i] >> 4) & 0x0f;
retbuf[j++] = Py_hexdigits[c];
c = argbuf[i] & 0x0f;
retbuf[j++] = Py_hexdigits[c];
if (bytes_per_sep_group && i < arglen - 1) {
Py_ssize_t anchor;
anchor = (bytes_per_sep_group > 0) ? (arglen - 1 - i) : (i + 1);
if (anchor % abs_bytes_per_sep == 0) {
unsigned char c;

if (bytes_per_sep_group == 0) {
for (i = j = 0; i < arglen; ++i) {
assert((j + 1) < resultlen);
c = argbuf[i];
retbuf[j++] = Py_hexdigits[c >> 4];
retbuf[j++] = Py_hexdigits[c & 0x0f];
}
assert(j == resultlen);
}
else {
/* The number of complete chunk+sep periods */
Py_ssize_t chunks = (arglen - 1) / abs_bytes_per_sep;
Py_ssize_t chunk;
unsigned int k;

if (bytes_per_sep_group < 0) {
i = j = 0;
for (chunk = 0; chunk < chunks; chunk++) {
for (k = 0; k < abs_bytes_per_sep; k++) {
c = argbuf[i++];
retbuf[j++] = Py_hexdigits[c >> 4];
retbuf[j++] = Py_hexdigits[c & 0x0f];
}
retbuf[j++] = sep_char;
}
while (i < arglen) {
c = argbuf[i++];
retbuf[j++] = Py_hexdigits[c >> 4];
retbuf[j++] = Py_hexdigits[c & 0x0f];
}
assert(j == resultlen);
}
else {
i = arglen - 1;
j = resultlen - 1;
for (chunk = 0; chunk < chunks; chunk++) {
for (k = 0; k < abs_bytes_per_sep; k++) {
c = argbuf[i--];
retbuf[j--] = Py_hexdigits[c & 0x0f];
retbuf[j--] = Py_hexdigits[c >> 4];
}
retbuf[j--] = sep_char;
}
while (i >= 0) {
c = argbuf[i--];
retbuf[j--] = Py_hexdigits[c & 0x0f];
retbuf[j--] = Py_hexdigits[c >> 4];
}
assert(j == -1);
}
}
assert(j == resultlen);

#ifdef Py_DEBUG
if (!return_bytes) {
Expand Down

0 comments on commit 6a9e80a

Please sign in to comment.