Rev 101: Updating on-the fly turns out to be more expensive than in http://bazaar.launchpad.net/~meliae-dev/meliae/trunk
John Arbash Meinel
john at arbash-meinel.com
Tue Oct 20 21:27:28 BST 2009
At http://bazaar.launchpad.net/~meliae-dev/meliae/trunk
------------------------------------------------------------
revno: 101
revision-id: john at arbash-meinel.com-20091020202715-07r2ahx4p2kw0n62
parent: john at arbash-meinel.com-20091018183641-kuogpd69cibpysc1
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: trunk
timestamp: Tue 2009-10-20 15:27:15 -0500
message:
Updating on-the fly turns out to be more expensive than
collapsing everything and updating at the end.
My guess is that the ref-list rebuilding is causing issues with
refcounts and gc stuff.
-------------- next part --------------
=== modified file 'meliae/loader.py'
--- a/meliae/loader.py 2009-10-18 18:36:41 +0000
+++ b/meliae/loader.py 2009-10-20 20:27:15 +0000
@@ -313,6 +313,11 @@
So we collapse those references back into the object, and grow its
'size' at the same time.
+
+ :param update_referrers: When removing the instance's __dict__
+ variable, update all references. If there are lots of things to
+ update, it is often faster to collapse everything, and then update
+ after-the-fact.
"""
# The instances I'm focusing on have a custom type name, and every
# instance has 2 pointers. The first is to __dict__, and the second is
@@ -320,15 +325,19 @@
# Also __dict__ has only 1 referrer, and that is *this* object
collapsed = 0
total = len(self.objs)
- for address, obj in self.objs.items():
+ for item_idx, (address, obj) in enumerate(self.objs.items()):
+ if obj.type_str in ('str', 'dict', 'tuple', 'list', 'type',
+ 'function', 'wrapper_descriptor',
+ 'code', 'classobj', 'int',
+ 'weakref'):
+ continue
+ if self.show_progress and item_idx & 0x5ff:
+ sys.stderr.write('checked %8d / %8d collapsed %8d \r'
+ % (item_idx, total, collapsed))
if obj.type_str == 'module' and obj.num_refs == 1:
(dict_ref,) = obj.ref_list
extra_refs = []
else:
- if obj.type_str in ('str', 'dict', 'tuple', 'list', 'type',
- 'function', 'wrapper_descriptor',
- 'code', 'classobj'):
- continue
if obj.num_refs != 2:
continue
(dict_ref, type_ref) = obj.ref_list
@@ -343,17 +352,7 @@
or dict_obj.referrers[0] != address):
continue
collapsed += 1
- if self.show_progress and collapsed & 0xff == 0:
- sys.stderr.write('collapsed %8d / %8d \r'
- % (collapsed, total))
# We found an instance \o/
- for ref in dict_obj.ref_list:
- referenced_obj = self.objs[ref]
- referrers = referenced_obj.referrers
- for idx in xrange(len(referrers)):
- if referrers[idx] == dict_ref:
- referrers[idx] = address
- referenced_obj.referrers = referrers
obj.ref_list = dict_obj.ref_list + extra_refs
obj.size = obj.size + dict_obj.size
obj.total_size = 0
@@ -361,8 +360,10 @@
# the dict from the collection
del self.objs[dict_ref]
if self.show_progress:
- sys.stderr.write('collapsed %8d / %8d => %8d \n'
- % (collapsed, total, len(self.objs)))
+ sys.stderr.write('checked %8d / %8d collapsed %8d \r'
+ % (item_idx, total, collapsed))
+ if collapsed:
+ self.compute_referrers()
def refs_as_dict(self, obj):
"""Expand the ref list considering it to be a 'dict' structure.
More information about the bazaar-commits
mailing list