D1938: ui: Improve ui.write performance when not coloring on Windows

joerg.sonnenberger (Joerg Sonnenberger) phabricator at mercurial-scm.org
Thu Jan 25 15:15:26 EST 2018


joerg.sonnenberger updated this revision to Diff 5005.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1938?vs=5003&id=5005

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,28 @@
         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)
+
+    from itertools import izip_longest
+    def grouper(iterable, n):
+        args = [iter(iterable)] * n
+        return izip_longest(*args, fillvalue=('', ''))
+
+    if fp is None and ui.writenolabels():
+        for block in grouper(chunksiter, 512):
+            write(*(chunk for chunk, label in block))
+    elif fp is None and ui.canbatchlabelwrites():
+        for block in grouper(chunksiter, 512):
+            output = []
+            for chunk, label in block:
+                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


More information about the Mercurial-devel mailing list