Mercurial > cpython-lru_cache-weakref
diff Python/bltinmodule.c @ 43657:08ee256a9bd1 legacy-trunk
Optimize sum() for integer and float inputs.
| author | Raymond Hettinger <python@rcn.com> |
|---|---|
| date | Wed, 24 Oct 2007 01:28:33 +0000 |
| parents | 9a447514855f |
| children | 7408e1ae98c4 |
line wrap: on
line diff
--- a/Python/bltinmodule.c Tue Oct 23 21:23:07 2007 +0000 +++ b/Python/bltinmodule.c Wed Oct 24 01:28:33 2007 +0000 @@ -2066,6 +2066,76 @@ 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(;;) { item = PyIter_Next(iter); if (item == NULL) {
