mirror of
https://github.com/python/cpython.git
synced 2025-07-28 21:55:21 +00:00
Optimize sum() for integer and float inputs.
This commit is contained in:
parent
cd3c108ca1
commit
3f8caa3ba7
2 changed files with 72 additions and 0 deletions
|
@ -12,6 +12,8 @@ What's New in Python 2.6 alpha 1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- optimize the performance of builtin.sum().
|
||||||
|
|
||||||
- Fix warnings found by the new version of the Coverity checker.
|
- Fix warnings found by the new version of the Coverity checker.
|
||||||
|
|
||||||
- The enumerate() builtin function is no longer bounded to sequences smaller
|
- The enumerate() builtin function is no longer bounded to sequences smaller
|
||||||
|
|
|
@ -2066,6 +2066,76 @@ builtin_sum(PyObject *self, PyObject *args)
|
||||||
Py_INCREF(result);
|
Py_INCREF(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SLOW_SUM
|
||||||
|
/* Fast addition by keeping temporary sums in C instead of new Python objects.
|
||||||
|
Assumes all inputs are the same type. If the assumption fails, default
|
||||||
|
to the more general routine.
|
||||||
|
*/
|
||||||
|
if (PyInt_CheckExact(result)) {
|
||||||
|
long i_result = PyInt_AS_LONG(result);
|
||||||
|
Py_DECREF(result);
|
||||||
|
result = NULL;
|
||||||
|
while(result == NULL) {
|
||||||
|
item = PyIter_Next(iter);
|
||||||
|
if (item == NULL) {
|
||||||
|
Py_DECREF(iter);
|
||||||
|
if (PyErr_Occurred())
|
||||||
|
return NULL;
|
||||||
|
return PyInt_FromLong(i_result);
|
||||||
|
}
|
||||||
|
if (PyInt_CheckExact(item)) {
|
||||||
|
long b = PyInt_AS_LONG(item);
|
||||||
|
long x = i_result + b;
|
||||||
|
if ((x^i_result) >= 0 || (x^b) >= 0) {
|
||||||
|
i_result = x;
|
||||||
|
Py_DECREF(item);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Either overflowed or is not an int. Restore real objects and process normally */
|
||||||
|
result = PyInt_FromLong(i_result);
|
||||||
|
temp = PyNumber_Add(result, item);
|
||||||
|
Py_DECREF(result);
|
||||||
|
Py_DECREF(item);
|
||||||
|
result = temp;
|
||||||
|
if (result == NULL) {
|
||||||
|
Py_DECREF(iter);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyFloat_CheckExact(result)) {
|
||||||
|
double f_result = PyFloat_AS_DOUBLE(result);
|
||||||
|
Py_DECREF(result);
|
||||||
|
result = NULL;
|
||||||
|
while(result == NULL) {
|
||||||
|
item = PyIter_Next(iter);
|
||||||
|
if (item == NULL) {
|
||||||
|
Py_DECREF(iter);
|
||||||
|
if (PyErr_Occurred())
|
||||||
|
return NULL;
|
||||||
|
return PyFloat_FromDouble(f_result);
|
||||||
|
}
|
||||||
|
if (PyFloat_CheckExact(item)) {
|
||||||
|
PyFPE_START_PROTECT("add", return 0)
|
||||||
|
f_result += PyFloat_AS_DOUBLE(item);
|
||||||
|
PyFPE_END_PROTECT(a)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result = PyFloat_FromDouble(f_result);
|
||||||
|
temp = PyNumber_Add(result, item);
|
||||||
|
Py_DECREF(result);
|
||||||
|
Py_DECREF(item);
|
||||||
|
result = temp;
|
||||||
|
if (result == NULL) {
|
||||||
|
Py_DECREF(iter);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
item = PyIter_Next(iter);
|
item = PyIter_Next(iter);
|
||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue