[pypy-commit] pypy default: (arigo, ltratt) Avoid allocating memory when ordereddicts have spare capacity.

ltratt noreply at buildbot.pypy.org
Mon Dec 15 16:36:14 CET 2014


Author: Laurence Tratt <laurie at tratt.net>
Branch: 
Changeset: r74939:7ff0e531c521
Date: 2014-12-15 15:35 +0000
http://bitbucket.org/pypy/pypy/changeset/7ff0e531c521/

Log:	(arigo, ltratt) Avoid allocating memory when ordereddicts have spare
	capacity.

	Previously, dicts could yo-yo in size if someone continually added
	and removed elements, but the total number of live elements remained
	more-or-less constant. This patch changes things so that compaction
	of entries happens more often than shrinking of memory. Put another
	way, we only shrink the size allocated to an ordereddict when it is
	extremely sparsely populated. This reduces GC pressure quite a bit.

diff --git a/rpython/rtyper/lltypesystem/rordereddict.py b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -575,7 +575,11 @@
 
 @jit.dont_look_inside
 def ll_dict_grow(d):
-    if d.num_items < d.num_used_items // 4:
+    if d.num_items < d.num_used_items // 2:
+        # At least 50% of the allocated entries are dead, so perform a
+        # compaction. If ll_dict_remove_deleted_items detects that over
+        # 75% of allocated entries are dead, then it will also shrink the
+        # memory allocated at the same time as doing a compaction.
         ll_dict_remove_deleted_items(d)
         return True
 
@@ -594,8 +598,10 @@
     return False
 
 def ll_dict_remove_deleted_items(d):
-    new_allocated = _overallocate_entries_len(d.num_items)
-    if new_allocated < len(d.entries) // 2:
+    if d.num_items < len(d.entries) // 4:
+        # At least 75% of the allocated entries are dead, so shrink the memory
+        # allocated as well as doing a compaction.
+        new_allocated = _overallocate_entries_len(d.num_items)
         newitems = lltype.malloc(lltype.typeOf(d).TO.entries.TO, new_allocated)
     else:
         newitems = d.entries


More information about the pypy-commit mailing list