mirror of
https://github.com/python/cpython.git
synced 2025-12-04 08:34:25 +00:00
long_format(): Easy speedup for output bases that aren't a power of 2 (in
particular, str(long) and repr(long) use base 10, and that gets a factor of 4 speedup). Another factor of 2 can be gotten by refactoring divrem1 to support in-place division, but that started getting messy so I'm leaving that out.
This commit is contained in:
parent
a3253d70bc
commit
fad225f1ba
1 changed files with 26 additions and 9 deletions
|
|
@ -811,28 +811,45 @@ long_format(PyObject *aa, int base, int addL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* Not 0, and base not a power of 2. Divide repeatedly by
|
||||||
|
base, but for speed use the highest power of base that
|
||||||
|
fits in a digit. */
|
||||||
|
digit powbase = base; /* powbase == base ** power */
|
||||||
|
int power = 1;
|
||||||
|
for (;;) {
|
||||||
|
unsigned long newpow = powbase * (unsigned long)base;
|
||||||
|
if (newpow >> SHIFT) /* doesn't fit in a digit */
|
||||||
|
break;
|
||||||
|
powbase = (digit)newpow;
|
||||||
|
++power;
|
||||||
|
}
|
||||||
|
|
||||||
Py_INCREF(a);
|
Py_INCREF(a);
|
||||||
do {
|
do {
|
||||||
|
int ntostore = power;
|
||||||
digit rem;
|
digit rem;
|
||||||
PyLongObject *temp = divrem1(a, (digit)base, &rem);
|
PyLongObject *temp = divrem1(a, powbase, &rem);
|
||||||
|
Py_DECREF(a);
|
||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
Py_DECREF(a);
|
|
||||||
Py_DECREF(str);
|
Py_DECREF(str);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (rem < 10)
|
|
||||||
rem += '0';
|
|
||||||
else
|
|
||||||
rem += 'A'-10;
|
|
||||||
assert(p > PyString_AS_STRING(str));
|
|
||||||
*--p = (char) rem;
|
|
||||||
Py_DECREF(a);
|
|
||||||
a = temp;
|
a = temp;
|
||||||
SIGCHECK({
|
SIGCHECK({
|
||||||
Py_DECREF(a);
|
Py_DECREF(a);
|
||||||
Py_DECREF(str);
|
Py_DECREF(str);
|
||||||
return NULL;
|
return NULL;
|
||||||
})
|
})
|
||||||
|
while (--ntostore >= 0) {
|
||||||
|
digit nextrem = (digit)(rem / base);
|
||||||
|
char c = (char)(rem - nextrem * base);
|
||||||
|
assert(p > PyString_AS_STRING(str));
|
||||||
|
c += (c < 10) ? '0' : 'A'-10;
|
||||||
|
*--p = c;
|
||||||
|
rem = nextrem;
|
||||||
|
if (a->ob_size == 0 && rem == 0)
|
||||||
|
break; /* skip leading zeroes */
|
||||||
|
}
|
||||||
} while (ABS(a->ob_size) != 0);
|
} while (ABS(a->ob_size) != 0);
|
||||||
Py_DECREF(a);
|
Py_DECREF(a);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue