[Python-Dev] Caching float(0.0)
Josiah Carlson
jcarlson at uci.edu
Wed Oct 4 07:35:43 CEST 2006
Steve Holden <steve at holdenweb.com> wrote:
> Josiah Carlson wrote:
> [yet more on this topic]
>
> If the brainpower already expended on this issue were proportional to
> its significance then we'd be reading about it on CNN news.
Goodness, I wasn't aware that pointer manipulation took that much
brainpower. I presume you mean what others have spent time thinking
about with regards to this topic.
> This thread has disappeared down a rat-hole, never to re-emerge with
> anything of significant benefit to users. C'mon, guys, implement a patch
> or leave it alone :-)
Heh. So be it. The following is untested (I lack a build system for
the Python trunk). It adds a new global cache for floats, a new 'fill
the global cache' function, and an updated PyFloat_FromDouble() function.
All in all, it took about 10 minutes to generate, and understands the
difference between fp +0.0 and -0.0 (assuming sane IEEE 754 fp double
behavior on non-x86 platforms).
- Josiah
/* This should go into floatobject.c */
static PyFloatObject *cached_list = NULL;
static PyFloatObject *
fill_cached_list(void)
{
cached_list = (PyFloatObject *) 1;
PyFloatObject *p;
int i;
p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatObject)*22);
if (p == NULL) {
cached_list = NULL;
return (PyFloatObject *) PyErr_NoMemory();
}
for (i=0;i<=10;i++) {
p[i] = (PyFloatObject*) PyFloat_fromDouble((double) i);
p[21-i] = (PyFloatObject*) PyFloat_fromDouble(-((double) i));
}
cached_list = NULL;
return p;
}
PyObject *
PyFloat_FromDouble(double fval)
{
register PyFloatObject *op;
register long* fvali = (int*)(&fval);
if (free_list == NULL) {
if ((free_list = fill_free_list()) == NULL)
return NULL;
}
#ifdef LITTLE_ENDIAN
if (!p[0])
#else
if (!p[1])
#endif
{
if (cached_list == NULL) {
if ((cached_list = fill_cached_list()) == NULL)
return NULL;
}
if ((cached_list != 1) && (cached_list != NULL)) {
#ifdef LITTLE_ENDIAN
switch p[1]
#else
switch p[0]
#endif
{
case 0: PY_INCREF(cached_list[0]); return cached_list[0];
case 1072693248: PY_INCREF(cached_list[1]); return cached_list[1];
case 1073741824: PY_INCREF(cached_list[2]); return cached_list[2];
case 1074266112: PY_INCREF(cached_list[3]); return cached_list[3];
case 1074790400: PY_INCREF(cached_list[4]); return cached_list[4];
case 1075052544: PY_INCREF(cached_list[5]); return cached_list[5];
case 1075314688: PY_INCREF(cached_list[6]); return cached_list[6];
case 1075576832: PY_INCREF(cached_list[7]); return cached_list[7];
case 1075838976: PY_INCREF(cached_list[8]); return cached_list[8];
case 1075970048: PY_INCREF(cached_list[9]); return cached_list[9];
case 1076101120: PY_INCREF(cached_list[10]); return cached_list[10];
case -1071382528: PY_INCREF(cached_list[11]); return cached_list[11];
case -1071513600: PY_INCREF(cached_list[12]); return cached_list[12];
case -1071644672: PY_INCREF(cached_list[13]); return cached_list[13];
case -1071906816: PY_INCREF(cached_list[14]); return cached_list[14];
case -1072168960: PY_INCREF(cached_list[15]); return cached_list[15];
case -1072431104: PY_INCREF(cached_list[16]); return cached_list[16];
case -1072693248: PY_INCREF(cached_list[17]); return cached_list[17];
case -1073217536: PY_INCREF(cached_list[18]); return cached_list[18];
case -1073741824: PY_INCREF(cached_list[19]); return cached_list[19];
case -1074790400: PY_INCREF(cached_list[20]); return cached_list[20];
case -2147483648: PY_INCREF(cached_list[21]); return cached_list[21];
default:
}
}
}
/* Inline PyObject_New */
op = free_list;
free_list = (PyFloatObject *)op->ob_type;
PyObject_INIT(op, &PyFloat_Type);
op->ob_fval = fval;
return (PyObject *) op;
}
More information about the Python-Dev
mailing list