diff options
author | Christian Heimes <christian@cheimes.de> | 2008-02-07 17:15:30 (GMT) |
---|---|---|
committer | Christian Heimes <christian@cheimes.de> | 2008-02-07 17:15:30 (GMT) |
commit | b4ee4a16f4fc28d89ba9b139db6cbaace44fc47a (patch) | |
tree | cd943a8da90412579b4e7f0392f52cc61ee219c5 /Objects | |
parent | 9521f08b98b3c0de6dc35f753eb07da33786f866 (diff) | |
download | cpython-b4ee4a16f4fc28d89ba9b139db6cbaace44fc47a.zip cpython-b4ee4a16f4fc28d89ba9b139db6cbaace44fc47a.tar.gz cpython-b4ee4a16f4fc28d89ba9b139db6cbaace44fc47a.tar.bz2 |
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.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/dictobject.c | 25 | ||||
-rw-r--r-- | Objects/listobject.c | 29 |
2 files changed, 54 insertions, 0 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c index e0ac475..82d247f 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -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 @@ -200,6 +216,9 @@ PyDict_New(void) #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 @@ 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 diff --git a/Objects/listobject.c b/Objects/listobject.c index 9e893662..df7a405 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -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; |