Mercurial > hg
changeset 18649:0969980308c7
dirstate: disable gc while parsing the dirstate
This prevents a performance regression an upcoming patch would otherwise
introduce because it indirectly delays parsing the dirstate a bit.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Sun, 10 Feb 2013 16:23:14 +0000 |
parents | 76b69cccb07a |
children | de0bd4bfc6d7 |
files | mercurial/dirstate.py |
diffstat | 1 files changed, 18 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/dirstate.py Fri Feb 08 22:54:17 2013 +0100 +++ b/mercurial/dirstate.py Sun Feb 10 16:23:14 2013 +0000 @@ -9,7 +9,7 @@ from node import nullid from i18n import _ import scmutil, util, ignore, osutil, parsers, encoding -import os, stat, errno +import os, stat, errno, gc propertycache = util.propertycache filecache = scmutil.filecache @@ -285,7 +285,23 @@ if not st: return - p = parsers.parse_dirstate(self._map, self._copymap, st) + # Python's garbage collector triggers a GC each time a certain number + # of container objects (the number being defined by + # gc.get_threshold()) are allocated. parse_dirstate creates a tuple + # for each file in the dirstate. The C version then immediately marks + # them as not to be tracked by the collector. However, this has no + # effect on when GCs are triggered, only on what objects the GC looks + # into. This means that O(number of files) GCs are unavoidable. + # Depending on when in the process's lifetime the dirstate is parsed, + # this can get very expensive. As a workaround, disable GC while + # parsing the dirstate. + gcenabled = gc.isenabled() + gc.disable() + try: + p = parsers.parse_dirstate(self._map, self._copymap, st) + finally: + if gcenabled: + gc.enable() if not self._dirtypl: self._pl = p