Mercurial > public > mercurial-scm > hg
comparison mercurial/context.py @ 27064:a29db426c5ba
context: avoid extra parents lookups
Resolving parents requires reading from the changelog, which is a few
attributes and function calls away. Parents lookup occurs surprisingly
often. Micro optimizing the code to avoid redundant lookups of parents
appears to make `hg log` on my Firefox repo a little faster:
before: 24.91s
after: 23.76s
delta: -1.15s (95.4% of original)
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 21 Nov 2015 19:21:01 -0800 |
parents | 37e1fdcb271c |
children | 0945539a3a6b |
comparison
equal
deleted
inserted
replaced
27063:37e1fdcb271c | 27064:a29db426c5ba |
---|---|
219 | 219 |
220 def p1(self): | 220 def p1(self): |
221 return self._parents[0] | 221 return self._parents[0] |
222 | 222 |
223 def p2(self): | 223 def p2(self): |
224 if len(self._parents) == 2: | 224 parents = self._parents |
225 return self._parents[1] | 225 if len(parents) == 2: |
226 return changectx(self._repo, -1) | 226 return parents[1] |
227 return changectx(self._repo, nullrev) | |
227 | 228 |
228 def _fileinfo(self, path): | 229 def _fileinfo(self, path): |
229 if '_manifest' in self.__dict__: | 230 if '_manifest' in self.__dict__: |
230 try: | 231 try: |
231 return self._manifest[path], self._manifest.flags(path) | 232 return self._manifest[path], self._manifest.flags(path) |
1150 def _buildflagfunc(self): | 1151 def _buildflagfunc(self): |
1151 # Create a fallback function for getting file flags when the | 1152 # Create a fallback function for getting file flags when the |
1152 # filesystem doesn't support them | 1153 # filesystem doesn't support them |
1153 | 1154 |
1154 copiesget = self._repo.dirstate.copies().get | 1155 copiesget = self._repo.dirstate.copies().get |
1155 | 1156 parents = self.parents() |
1156 if len(self._parents) < 2: | 1157 if len(parents) < 2: |
1157 # when we have one parent, it's easy: copy from parent | 1158 # when we have one parent, it's easy: copy from parent |
1158 man = self._parents[0].manifest() | 1159 man = parents[0].manifest() |
1159 def func(f): | 1160 def func(f): |
1160 f = copiesget(f, f) | 1161 f = copiesget(f, f) |
1161 return man.flags(f) | 1162 return man.flags(f) |
1162 else: | 1163 else: |
1163 # merges are tricky: we try to reconstruct the unstored | 1164 # merges are tricky: we try to reconstruct the unstored |
1164 # result from the merge (issue1802) | 1165 # result from the merge (issue1802) |
1165 p1, p2 = self._parents | 1166 p1, p2 = parents |
1166 pa = p1.ancestor(p2) | 1167 pa = p1.ancestor(p2) |
1167 m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest() | 1168 m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest() |
1168 | 1169 |
1169 def func(f): | 1170 def func(f): |
1170 f = copiesget(f, f) # may be wrong for merges with copies | 1171 f = copiesget(f, f) # may be wrong for merges with copies |
1190 This reuse the file nodeid from parent, but we append an extra letter | 1191 This reuse the file nodeid from parent, but we append an extra letter |
1191 when modified. Modified files get an extra 'm' while added files get | 1192 when modified. Modified files get an extra 'm' while added files get |
1192 an extra 'a'. This is used by manifests merge to see that files | 1193 an extra 'a'. This is used by manifests merge to see that files |
1193 are different and by update logic to avoid deleting newly added files. | 1194 are different and by update logic to avoid deleting newly added files. |
1194 """ | 1195 """ |
1195 | 1196 parents = self.parents() |
1196 man1 = self._parents[0].manifest() | 1197 |
1198 man1 = parents[0].manifest() | |
1197 man = man1.copy() | 1199 man = man1.copy() |
1198 if len(self._parents) > 1: | 1200 if len(parents) > 1: |
1199 man2 = self.p2().manifest() | 1201 man2 = self.p2().manifest() |
1200 def getman(f): | 1202 def getman(f): |
1201 if f in man1: | 1203 if f in man1: |
1202 return man1 | 1204 return man1 |
1203 return man2 | 1205 return man2 |