joerg.sonnenberger created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers.
REVISION SUMMARY For ``hg diff``, ui.write appears as super hot in the profile with up to 60% time spend in it for larger diffs. Introduce two predicates to decide if label processing is active at all and if it is, whether the result can still be simply batched up. If either case is true, process all chunks of a file in one go and use ``ui.write`` once. This reduces the time of ``hg diff`` from 3m54s to 2m26s for the test case. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1938 AFFECTED FILES mercurial/cmdutil.py mercurial/ui.py CHANGE DETAILS diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -878,6 +878,18 @@ return "".join(self._buffers.pop()) + def writenolabels(self, **opts): + '''check if write actually uses the label''' + if self._buffers and not opts.get(r'prompt', False): + if not self._bufferapplylabels: + return True + return self._colormode is None + def canbatchlabelwrites(self, **opts): + '''check if write calls with labels are batchable''' + assert not self.writenolabels() + # Windows color printing is special, see ``write``. + return self._colormode != 'win32' + def write(self, *args, **opts): '''write args to output diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1615,14 +1615,21 @@ chunks = patch.diff(repo, node1, node2, match, changes, opts=diffopts, prefix=prefix, relroot=relroot, hunksfilterfn=hunksfilterfn) - for chunk, label in patch.diffstatui(util.iterlines(chunks), - width=width): - write(chunk, label=label) + chunksiter = patch.diffstatui(util.iterlines(chunks), width=width) else: - for chunk, label in patch.diffui(repo, node1, node2, match, - changes, opts=diffopts, prefix=prefix, - relroot=relroot, - hunksfilterfn=hunksfilterfn): + chunksiter = patch.diffui(repo, node1, node2, match, changes, + opts=diffopts, prefix=prefix, + relroot=relroot, hunksfilterfn=hunksfilterfn) + + if fp is None and ui.writenolabels(): + write(*(chunk for chunk, label in chunksiter)) + elif fp is None and ui.canbatchlabelwrites(): + output = [] + for chunk, label in chunksiter: + output.append(ui.label(chunk, label=label)) + write(*output) + else: + for chunk, label in chunksiter: write(chunk, label=label) if listsubrepos: To: joerg.sonnenberger, #hg-reviewers Cc: mercurial-devel _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel