@@ -305,14 +305,18 @@ PyDict_Fini(void)
305305 * #define USABLE_FRACTION(n) (((n) >> 1) + ((n) >> 2) - ((n) >> 3))
306306*/
307307
308- /* GROWTH_RATE. Growth rate upon hitting maximum load. Currently set to *2.
309- * Raising this to *4 doubles memory consumption depending on the size of
308+ /* GROWTH_RATE. Growth rate upon hitting maximum load.
309+ * Currently set to used*2 + capacity/2.
310+ * This means that dicts double in size when growing without deletions,
311+ * but have more head room when the number of deletions is on a par with the
312+ * number of insertions.
313+ * Raising this to used*4 doubles memory consumption depending on the size of
310314 * the dictionary, but results in half the number of resizes, less effort to
311- * resize and better sparseness for some (but not all dict sizes) .
312- * Setting to *4 eliminates every other resize step .
313- * GROWTH_RATE was set to *4 up to version 3.2.
315+ * resize.
316+ * GROWTH_RATE was set to used *4 up to version 3.2 .
317+ * GROWTH_RATE was set to used*2 in version 3.3.0
314318 */
315- #define GROWTH_RATE (x ) ((x) * 2 )
319+ #define GROWTH_RATE (d ) (((d)->ma_used*2)+((d)->ma_keys->dk_size>>1) )
316320
317321#define ENSURE_ALLOWS_DELETIONS (d ) \
318322 if ((d)->ma_keys->dk_lookup == lookdict_unicode_nodummy) { \
@@ -790,7 +794,7 @@ find_empty_slot(PyDictObject *mp, PyObject *key, Py_hash_t hash,
790794static int
791795insertion_resize (PyDictObject * mp )
792796{
793- return dictresize (mp , GROWTH_RATE (mp -> ma_used ));
797+ return dictresize (mp , GROWTH_RATE (mp ));
794798}
795799
796800/*
0 commit comments