[Python-Dev] Caching float(0.0)

skip at pobox.com skip at pobox.com
Sun Oct 1 00:37:49 CEST 2006


    Steve> By these statistics I think the answer to the original question
    Steve> is clearly "no" in the general case.

As someone else (Guido?) pointed out, the literal case isn't all that
interesting.  I modified floatobject.c to track a few interesting
floating point values:

    static unsigned int nfloats[5] = {
            0, /* -1.0 */
            0, /*  0.0 */
            0, /* +1.0 */
            0, /* everything else */
            0, /* whole numbers from -10.0 ... 10.0 */
    };

    PyObject *
    PyFloat_FromDouble(double fval)
    {
            register PyFloatObject *op;
            if (free_list == NULL) {
                    if ((free_list = fill_free_list()) == NULL)
                            return NULL;
            }

            if (fval == 0.0) nfloats[1]++;
            else if (fval == 1.0) nfloats[2]++;
            else if (fval == -1.0) nfloats[0]++;
            else nfloats[3]++;

            if (fval >= -10.0 && fval <= 10.0 && (int)fval == fval) {
                    nfloats[4]++;
            }

            /* Inline PyObject_New */
            op = free_list;
            free_list = (PyFloatObject *)op->ob_type;
            PyObject_INIT(op, &PyFloat_Type);
            op->ob_fval = fval;
            return (PyObject *) op;
    }

    static void
    _count_float_allocations(void)
    {
            fprintf(stderr, "-1.0: %d\n", nfloats[0]);
            fprintf(stderr, " 0.0: %d\n", nfloats[1]);
            fprintf(stderr, "+1.0: %d\n", nfloats[2]);
            fprintf(stderr, "rest: %d\n", nfloats[3]);
            fprintf(stderr, "whole numbers -10.0 to 10.0: %d\n", nfloats[4]);
    }

then called atexit(_count_float_allocations) in _PyFloat_Init and ran "make
test".  The output was:

    ...
    ./python.exe -E -tt ../Lib/test/regrtest.py -l 
    ...
    -1.0: 29048
     0.0: 524241
    +1.0: 91561
    rest: 1749807
    whole numbers -10.0 to 10.0: 1151442

So for a largely non-floating point "application", a fair number of floats
are allocated, a bit over 25% of them are -1.0, 0.0 or +1.0, and nearly 50%
of them are whole numbers between -10.0 and 10.0, inclusive.

Seems like it at least deserves a serious look.  It would be nice to have
the numeric crowd contribute to this subject as well.

Skip



More information about the Python-Dev mailing list