Kaydet (Commit) b4ee4a16 authored tarafından Christian Heimes's avatar Christian Heimes

Added some statistics code to dict and list object code. I wanted to test how a…

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.
üst 9521f08b
...@@ -162,6 +162,22 @@ show_counts(void) ...@@ -162,6 +162,22 @@ show_counts(void)
} }
#endif #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. /* Initialization macros.
There are two ways to create a dict: PyDict_New() is the main C API 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 function, and the tp_new slot maps to dict_new(). In the latter case we
...@@ -199,6 +215,9 @@ PyDict_New(void) ...@@ -199,6 +215,9 @@ PyDict_New(void)
return NULL; return NULL;
#ifdef SHOW_CONVERSION_COUNTS #ifdef SHOW_CONVERSION_COUNTS
Py_AtExit(show_counts); Py_AtExit(show_counts);
#endif
#ifdef SHOW_ALLOC_COUNT
Py_AtExit(show_alloc);
#endif #endif
} }
if (numfree) { if (numfree) {
...@@ -212,11 +231,17 @@ PyDict_New(void) ...@@ -212,11 +231,17 @@ PyDict_New(void)
assert (mp->ma_used == 0); assert (mp->ma_used == 0);
assert (mp->ma_table == mp->ma_smalltable); assert (mp->ma_table == mp->ma_smalltable);
assert (mp->ma_mask == PyDict_MINSIZE - 1); assert (mp->ma_mask == PyDict_MINSIZE - 1);
#ifdef SHOW_ALLOC_COUNT
count_reuse++;
#endif
} else { } else {
mp = PyObject_GC_New(PyDictObject, &PyDict_Type); mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
if (mp == NULL) if (mp == NULL)
return NULL; return NULL;
EMPTY_TO_MINSIZE(mp); EMPTY_TO_MINSIZE(mp);
#ifdef SHOW_ALLOC_COUNT
count_alloc++;
#endif
} }
mp->ma_lookup = lookdict_string; mp->ma_lookup = lookdict_string;
#ifdef SHOW_CONVERSION_COUNTS #ifdef SHOW_CONVERSION_COUNTS
......
...@@ -63,6 +63,22 @@ list_resize(PyListObject *self, Py_ssize_t newsize) ...@@ -63,6 +63,22 @@ list_resize(PyListObject *self, Py_ssize_t newsize)
return 0; 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 */ /* Empty list reuse scheme to save calls to malloc and free */
#ifndef PyList_MAXFREELIST #ifndef PyList_MAXFREELIST
#define PyList_MAXFREELIST 80 #define PyList_MAXFREELIST 80
...@@ -88,6 +104,13 @@ PyList_New(Py_ssize_t size) ...@@ -88,6 +104,13 @@ PyList_New(Py_ssize_t size)
{ {
PyListObject *op; PyListObject *op;
size_t nbytes; size_t nbytes;
#ifdef SHOW_ALLOC_COUNT
static int initialized = 0;
if (!initialized) {
Py_AtExit(show_alloc);
initialized = 1;
}
#endif
if (size < 0) { if (size < 0) {
PyErr_BadInternalCall(); PyErr_BadInternalCall();
...@@ -101,10 +124,16 @@ PyList_New(Py_ssize_t size) ...@@ -101,10 +124,16 @@ PyList_New(Py_ssize_t size)
numfree--; numfree--;
op = free_list[numfree]; op = free_list[numfree];
_Py_NewReference((PyObject *)op); _Py_NewReference((PyObject *)op);
#ifdef SHOW_ALLOC_COUNT
count_reuse++;
#endif
} else { } else {
op = PyObject_GC_New(PyListObject, &PyList_Type); op = PyObject_GC_New(PyListObject, &PyList_Type);
if (op == NULL) if (op == NULL)
return NULL; return NULL;
#ifdef SHOW_ALLOC_COUNT
count_alloc++;
#endif
} }
if (size <= 0) if (size <= 0)
op->ob_item = NULL; op->ob_item = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment