[Python-checkins] r60646 - python/trunk/Objects/dictobject.c python/trunk/Objects/listobject.c

christian.heimes python-checkins at python.org
Thu Feb 7 18:15:30 CET 2008


Author: christian.heimes
Date: Thu Feb  7 18:15:30 2008
New Revision: 60646

Modified:
   python/trunk/Objects/dictobject.c
   python/trunk/Objects/listobject.c
Log:
Added some statistics code to dict and list object code. I wanted to test how a larger freelist affects the reusage of freed objects. Contrary to my gut feelings 80 objects is more than fine for small apps. I haven't profiled a large app yet.

Modified: python/trunk/Objects/dictobject.c
==============================================================================
--- python/trunk/Objects/dictobject.c	(original)
+++ python/trunk/Objects/dictobject.c	Thu Feb  7 18:15:30 2008
@@ -162,6 +162,22 @@
 }
 #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
@@ -200,6 +216,9 @@
 #ifdef SHOW_CONVERSION_COUNTS
 		Py_AtExit(show_counts);
 #endif
+#ifdef SHOW_ALLOC_COUNT
+		Py_AtExit(show_alloc);
+#endif
 	}
 	if (numfree) {
 		mp = free_list[--numfree];
@@ -212,11 +231,17 @@
 		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

Modified: python/trunk/Objects/listobject.c
==============================================================================
--- python/trunk/Objects/listobject.c	(original)
+++ python/trunk/Objects/listobject.c	Thu Feb  7 18:15:30 2008
@@ -63,6 +63,22 @@
 	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 @@
 {
 	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 @@
 		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;


More information about the Python-checkins mailing list