Low-hanging performance improvements #5664

Merged
merged 7 commits into from Dec 22, 2015
View
@@ -750,8 +750,8 @@ def reset_ticks(self):
# build a few default ticks; grow as necessary later; only
# define 1 so properties set on ticks will be copied as they
# grow
- cbook.popall(self.majorTicks)
- cbook.popall(self.minorTicks)
+ del self.majorTicks[:]
+ del self.minorTicks[:]
self.majorTicks.extend([self._get_tick(major=True)])
self.minorTicks.extend([self._get_tick(major=False)])
View
@@ -1392,12 +1392,6 @@ def remove(self, o):
self.push(thiso)
-def popall(seq):
- 'empty a list'
- for i in xrange(len(seq)):
- seq.pop()
-
-
def finddir(o, match, case=False):
"""
return all attributes of *o* which match string in match. if case
@@ -93,6 +93,8 @@
(TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN,
CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN) = list(xrange(8))
+_empty_path = Path(np.empty((0, 2)))
+
class MarkerStyle(object):
@@ -182,7 +184,7 @@ def __setstate__(self, statedict):
self._recache()
def _recache(self):
- self._path = Path(np.empty((0, 2)))
+ self._path = _empty_path
self._transform = IdentityTransform()
self._alt_path = None
self._alt_transform = None
@@ -278,7 +278,8 @@ def test_transform():
# Check parent -> child links of TransformWrapper.
assert_equal(obj.wrapper._child, obj.composite)
# Check child -> parent links of TransformWrapper.
- assert_equal(list(obj.wrapper._parents.values()), [obj.composite2])
+ assert_equal(
+ [v() for v in obj.wrapper._parents.values()], [obj.composite2])
# Check input and output dimensions are set as expected.
assert_equal(obj.wrapper.input_dims, obj.composite.input_dims)
assert_equal(obj.wrapper.output_dims, obj.composite.output_dims)
@@ -40,7 +40,7 @@
update_path_extents)
from numpy.linalg import inv
-from weakref import WeakValueDictionary
+import weakref
import warnings
try:
set
@@ -92,10 +92,7 @@ def __init__(self, shorthand_name=None):
other than to improve the readability of
``str(transform)`` when DEBUG=True.
"""
- # Parents are stored in a WeakValueDictionary, so that if the
- # parents are deleted, references from the children won't keep
- # them alive.
- self._parents = WeakValueDictionary()
+ self._parents = {}
# TransformNodes start out as invalid until their values are
# computed for the first time.
@@ -109,14 +106,17 @@ def __str__(self):
def __getstate__(self):
d = self.__dict__.copy()
- # turn the weakkey dictionary into a normal dictionary
- d['_parents'] = dict(six.iteritems(self._parents))
+ # turn the dictionary with weak values into a normal dictionary
+ d['_parents'] = dict((k, v()) for (k, v) in
@tacaswell

tacaswell Dec 22, 2015

Owner

Does this need a check that v() returns an active ref?

@mdboom

mdboom Dec 22, 2015

Owner

I currently check on deserializing (__setstate__) where you have to deal with it. No real need to do it in both places unless we really care about the size of the serialization.

@tacaswell

tacaswell Dec 22, 2015

Owner

fair enough.

+ six.iteritems(self._parents))
return d
def __setstate__(self, data_dict):
self.__dict__ = data_dict
- # turn the normal dictionary back into a WeakValueDictionary
- self._parents = WeakValueDictionary(self._parents)
+ # turn the normal dictionary back into a dictionary with weak
+ # values
+ self._parents = dict((k, weakref.ref(v)) for (k, v) in
+ six.iteritems(self._parents) if v is not None)
def __copy__(self, *args):
raise NotImplementedError(
@@ -156,8 +156,11 @@ def _invalidate_internal(self, value, invalidating_node):
self._invalid = value
for parent in list(six.itervalues(self._parents)):
- parent._invalidate_internal(value=value,
- invalidating_node=self)
+ # Dereference the weak reference
+ parent = parent()
+ if parent is not None:
+ parent._invalidate_internal(
+ value=value, invalidating_node=self)
def set_children(self, *children):
"""
@@ -166,8 +169,11 @@ def set_children(self, *children):
Should be called from the constructor of any transforms that
depend on other transforms.
"""
+ # Parents are stored as weak references, so that if the
+ # parents are destroyed, references from the children won't
+ # keep them alive.
for child in children:
- child._parents[id(self)] = self
+ child._parents[id(self)] = weakref.ref(self)
if DEBUG:
_set_children = set_children
@@ -1560,8 +1566,9 @@ def __getstate__(self):
'child': self._child,
'input_dims': self.input_dims,
'output_dims': self.output_dims,
- # turn the weakkey dictionary into a normal dictionary
- 'parents': dict(six.iteritems(self._parents))
+ # turn the weak-values dictionary into a normal dictionary
+ 'parents': dict((k, v()) for (k, v) in
+ six.iteritems(self._parents))
}
def __setstate__(self, state):
@@ -1570,8 +1577,10 @@ def __setstate__(self, state):
# The child may not be unpickled yet, so restore its information.
self.input_dims = state['input_dims']
self.output_dims = state['output_dims']
- # turn the normal dictionary back into a WeakValueDictionary
- self._parents = WeakValueDictionary(state['parents'])
+ # turn the normal dictionary back into a dictionary with weak
+ # values
+ self._parents = dict((k, weakref.ref(v)) for (k, v) in
+ six.iteritems(state['parents']) if v is not None)
def __repr__(self):
return "TransformWrapper(%r)" % self._child