comparison mercurial/localrepo.py @ 45464:4a0ccbecbaa6

repo: avoid copying/updating a dict on every `repo.__getitem__` This has some mild performance benefits. I'm looking into a pathological case where one of our `hg log` invocations takes several seconds, and according to hyperfine this reduces the wall time of the entire operation (running in chg) from: ``` Time (mean ? ?): 7.390 s ? 0.106 s [User: 7.058 s, System: 0.271 s] Range (min ? max): 7.300 s ? 7.625 s ``` to: ``` Time (mean ? ?): 7.046 s ? 0.091 s [User: 6.714 s, System: 0.279 s] Range (min ? max): 6.916 s ? 7.169 s ``` Note: the log command is slow due to an issue in our custom stuff executing `repo[<arg>]` 298,800 times. This performance improvement is likely not noticeable during normal operation, but I don't feel like it's making the code more difficult to understand, and every small bit helps. Differential Revision: https://phab.mercurial-scm.org/D9022
author Kyle Lippincott <spectral@google.com>
date Fri, 11 Sep 2020 15:52:06 -0700
parents 324ad3e7ef41
children d252f51ab032
comparison
equal deleted inserted replaced
45463:145cfe84d3e4 45464:4a0ccbecbaa6
1568 1568
1569 @unfilteredpropertycache 1569 @unfilteredpropertycache
1570 def _quick_access_changeid_wc(self): 1570 def _quick_access_changeid_wc(self):
1571 # also fast path access to the working copy parents 1571 # also fast path access to the working copy parents
1572 # however, only do it for filter that ensure wc is visible. 1572 # however, only do it for filter that ensure wc is visible.
1573 quick = {} 1573 quick = self._quick_access_changeid_null.copy()
1574 cl = self.unfiltered().changelog 1574 cl = self.unfiltered().changelog
1575 for node in self.dirstate.parents(): 1575 for node in self.dirstate.parents():
1576 if node == nullid: 1576 if node == nullid:
1577 continue 1577 continue
1578 rev = cl.index.get_rev(node) 1578 rev = cl.index.get_rev(node)
1607 """an helper dictionnary for __getitem__ calls 1607 """an helper dictionnary for __getitem__ calls
1608 1608
1609 This contains a list of symbol we can recognise right away without 1609 This contains a list of symbol we can recognise right away without
1610 further processing. 1610 further processing.
1611 """ 1611 """
1612 mapping = self._quick_access_changeid_null
1613 if self.filtername in repoview.filter_has_wc: 1612 if self.filtername in repoview.filter_has_wc:
1614 mapping = mapping.copy() 1613 return self._quick_access_changeid_wc
1615 mapping.update(self._quick_access_changeid_wc) 1614 return self._quick_access_changeid_null
1616 return mapping
1617 1615
1618 def __getitem__(self, changeid): 1616 def __getitem__(self, changeid):
1619 # dealing with special cases 1617 # dealing with special cases
1620 if changeid is None: 1618 if changeid is None:
1621 return context.workingctx(self) 1619 return context.workingctx(self)