obscache: shortcut the attribute access for testing
The attribute access adds a significant overhead. we can gain -20% performance
by doing so.
--- a/hgext3rd/evolve/obscache.py Thu Jun 01 03:35:45 2017 +0200
+++ b/hgext3rd/evolve/obscache.py Mon Jun 05 10:21:38 2017 +0100
@@ -364,18 +364,31 @@
super(obscache, self).__init__()
self._ondiskkey = None
self._vfs = repo.vfs
- self._data = bytearray()
+ self._setdata(bytearray())
+
+ @util.propertycache
+ def get(self):
+ """final signature: obscache.get(rev)
+
+ return True if "rev" is used as "precursors for any obsmarkers
- def get(self, rev):
- """return True if "rev" is used as "precursors for any obsmarkers
+ IMPORTANT: make sure the cache has been updated to match the repository
+ content before using it
- Make sure the cache has been updated to match the repository content before using it"""
- return self._data[rev]
+ We use a property cache to skip the attribute resolution overhead in
+ hot loops."""
+ return self._data.__getitem__
+
+ def _setdata(self, data):
+ """set a new bytearray data, invalidating the 'get' shortcut if needed"""
+ self._data = data
+ if 'get' in vars(self):
+ del self.get
def clear(self, reset=False):
"""invalidate the cache content"""
super(obscache, self).clear(reset=reset)
- self._data = bytearray()
+ self._setdata(bytearray())
def _updatefrom(self, repo, revs, obsmarkers):
if revs:
@@ -443,11 +456,11 @@
data = repo.vfs.tryread(self._filepath)
if not data:
self._cachekey = self.emptykey
- self._data = bytearray()
+ self._setdata(bytearray())
else:
headersize = struct.calcsize(self._headerformat)
self._cachekey = struct.unpack(self._headerformat, data[:headersize])
- self._data = bytearray(data[headersize:])
+ self._setdata(bytearray(data[headersize:]))
self._ondiskkey = self._cachekey
def _computeobsoleteset(orig, repo):