[PATCH] cat: increase perf when catting without patterns

Durham Goode durham at fb.com
Fri Jan 10 21:17:30 CST 2014


# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1389405865 28800
#      Fri Jan 10 18:04:25 2014 -0800
# Node ID c4d55205c7d81950d631debed3c044c82e87cbd9
# Parent  d2704c48f4176d8cd6f21d33500820d44763585c
cat: increase perf when catting without patterns

When running 'hg cat -r . <file>' it was doing an expensive ctx.walk(m). It's
much faster to just read that file directly. In our repo it shaves 60% off the
'hg cat' time.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1151,15 +1151,32 @@
     ctx = scmutil.revsingle(repo, opts.get('rev'))
     err = 1
     m = scmutil.match(ctx, (file1,) + pats, opts)
-    for abs in ctx.walk(m):
+
+    def write(path):
         fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
-                                 pathname=abs)
-        data = ctx[abs].data()
+                                 pathname=path)
+        data = ctx[path].data()
         if opts.get('decode'):
-            data = repo.wwritedata(abs, data)
+            data = repo.wwritedata(path, data)
         fp.write(data)
         fp.close()
-        err = 0
+
+    files = set(m.files())
+    files.discard('.')
+    if files and not m.anypats():
+        for file in sorted(list(files)):
+            try:
+                write(file)
+                err = 0
+            except error.ManifestLookupError:
+                # It's significantly cheaper to catch the exception than it
+                # is to do a 'file in ctx' check, due to makefileobj using
+                # manifest.find instead of manifest.read
+                m.bad(file, _('no such file in rev %s') % ctx)
+    else:
+        for abs in ctx.walk(m):
+            write(abs)
+            err = 0
     return err
 
 @command('^clone',


More information about the Mercurial-devel mailing list