diff: improve ui.write performance when not coloring on Windows
authorJoerg Sonnenberger <joerg@bec.de>
Sun, 04 Feb 2018 00:29:22 +0100
changeset 36000 0ff41ced4c12
parent 35999 580f7b1b88c7
child 36001 fa15a70f88de
diff: improve ui.write performance when not coloring on Windows Differential Revision: https://phab.mercurial-scm.org/D2022
mercurial/logcmdutil.py
mercurial/ui.py
--- a/mercurial/logcmdutil.py	Tue Feb 06 05:25:36 2018 -0500
+++ b/mercurial/logcmdutil.py	Sun Feb 04 00:29:22 2018 +0100
@@ -79,18 +79,31 @@
         width = 80
         if not ui.plain():
             width = ui.termwidth()
-        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)
+
+    chunks = patch.diff(repo, node1, node2, match, changes, opts=diffopts,
+                        prefix=prefix, relroot=relroot,
+                        hunksfilterfn=hunksfilterfn)
+
+    if fp is not None or ui.canwritewithoutlabels():
+        if stat:
+            chunks = patch.diffstat(util.iterlines(chunks), width=width)
+        for chunk in util.filechunkiter(util.chunkbuffer(chunks)):
+            write(chunk)
     else:
-        for chunk, label in patch.diffui(repo, node1, node2, match,
-                                         changes, opts=diffopts, prefix=prefix,
-                                         relroot=relroot,
-                                         hunksfilterfn=hunksfilterfn):
-            write(chunk, label=label)
+        if stat:
+            chunks = patch.diffstatui(util.iterlines(chunks), width=width)
+        else:
+            chunks = patch.difflabel(lambda chunks, **kwargs: chunks, chunks,
+                                     opts=diffopts)
+        if ui.canbatchlabeledwrites():
+            def gen():
+                for chunk, label in chunks:
+                    yield ui.label(chunk, label=label)
+            for chunk in util.filechunkiter(util.chunkbuffer(gen())):
+                write(chunk)
+        else:
+            for chunk, label in chunks:
+                write(chunk, label=label)
 
     if listsubrepos:
         ctx1 = repo[node1]
--- a/mercurial/ui.py	Tue Feb 06 05:25:36 2018 -0500
+++ b/mercurial/ui.py	Sun Feb 04 00:29:22 2018 +0100
@@ -870,6 +870,17 @@
 
         return "".join(self._buffers.pop())
 
+    def canwritewithoutlabels(self):
+        '''check if write skips the label'''
+        if self._buffers and not self._bufferapplylabels:
+            return True
+        return self._colormode is None
+
+    def canbatchlabeledwrites(self):
+        '''check if write calls with labels are batchable'''
+        # Windows color printing is special, see ``write``.
+        return self._colormode != 'win32'
+
     def write(self, *args, **opts):
         '''write args to output