]> granicus.if.org Git - python/commitdiff
Added some statistics code to dict and list object code. I wanted to test how a large...
authorChristian Heimes <christian@cheimes.de>
Thu, 7 Feb 2008 17:15:30 +0000 (17:15 +0000)
committerChristian Heimes <christian@cheimes.de>
Thu, 7 Feb 2008 17:15:30 +0000 (17:15 +0000)
Objects/dictobject.c
Objects/listobject.c

index e0ac475346af35a3f9c1571f72914038519edab4..82d247f3f9515309962e5355536f4784bff94192 100644 (file)
@@ -162,6 +162,22 @@ show_counts(void)
 }
 #endif
 
+/* Debug statistic to compare allocations with reuse through the free list */
+#undef SHOW_ALLOC_COUNT
+#ifdef SHOW_ALLOC_COUNT
+static size_t count_alloc = 0;
+static size_t count_reuse = 0;
+
+static void
+show_alloc(void)
+{
+       fprintf(stderr, "Dict allocations: %zd\n", count_alloc);
+       fprintf(stderr, "Dict reuse through freelist: %zd\n", count_reuse);
+       fprintf(stderr, "%.2f%% reuse rate\n\n",
+               (100.0*count_reuse/(count_alloc+count_reuse)));
+}
+#endif
+
 /* Initialization macros.
    There are two ways to create a dict:  PyDict_New() is the main C API
    function, and the tp_new slot maps to dict_new().  In the latter case we
@@ -199,6 +215,9 @@ PyDict_New(void)
                        return NULL;
 #ifdef SHOW_CONVERSION_COUNTS
                Py_AtExit(show_counts);
+#endif
+#ifdef SHOW_ALLOC_COUNT
+               Py_AtExit(show_alloc);
 #endif
        }
        if (numfree) {
@@ -212,11 +231,17 @@ PyDict_New(void)
                assert (mp->ma_used == 0);
                assert (mp->ma_table == mp->ma_smalltable);
                assert (mp->ma_mask == PyDict_MINSIZE - 1);
+#ifdef SHOW_ALLOC_COUNT
+               count_reuse++;
+#endif
        } else {
                mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
                if (mp == NULL)
                        return NULL;
                EMPTY_TO_MINSIZE(mp);
+#ifdef SHOW_ALLOC_COUNT
+               count_alloc++;
+#endif
        }
        mp->ma_lookup = lookdict_string;
 #ifdef SHOW_CONVERSION_COUNTS
index 9e893662b350630245a9202647f5a7ad306e2028..df7a405f1f49cd1d2a6861e9bc2eabe89b0c7276 100644 (file)
@@ -63,6 +63,22 @@ list_resize(PyListObject *self, Py_ssize_t newsize)
        return 0;
 }
 
+/* Debug statistic to compare allocations with reuse through the free list */
+#undef SHOW_ALLOC_COUNT
+#ifdef SHOW_ALLOC_COUNT
+static size_t count_alloc = 0;
+static size_t count_reuse = 0;
+
+static void
+show_alloc(void)
+{
+       fprintf(stderr, "List allocations: %zd\n", count_alloc);
+       fprintf(stderr, "List reuse through freelist: %zd\n", count_reuse);
+       fprintf(stderr, "%.2f%% reuse rate\n\n",
+               (100.0*count_reuse/(count_alloc+count_reuse)));
+}
+#endif
+
 /* Empty list reuse scheme to save calls to malloc and free */
 #ifndef PyList_MAXFREELIST
 #define PyList_MAXFREELIST 80
@@ -88,6 +104,13 @@ PyList_New(Py_ssize_t size)
 {
        PyListObject *op;
        size_t nbytes;
+#ifdef SHOW_ALLOC_COUNT
+       static int initialized = 0;
+       if (!initialized) {
+               Py_AtExit(show_alloc);
+               initialized = 1;
+       }
+#endif
 
        if (size < 0) {
                PyErr_BadInternalCall();
@@ -101,10 +124,16 @@ PyList_New(Py_ssize_t size)
                numfree--;
                op = free_list[numfree];
                _Py_NewReference((PyObject *)op);
+#ifdef SHOW_ALLOC_COUNT
+               count_reuse++;
+#endif
        } else {
                op = PyObject_GC_New(PyListObject, &PyList_Type);
                if (op == NULL)
                        return NULL;
+#ifdef SHOW_ALLOC_COUNT
+               count_alloc++;
+#endif
        }
        if (size <= 0)
                op->ob_item = NULL;