From patchwork Tue Jan 14 21:52:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [2,of,2,V2] cat: increase perf when catting single files From: Durham Goode X-Patchwork-Id: 3323 Message-Id: To: mercurial-devel@selenic.com Date: Tue, 14 Jan 2014 13:52:31 -0800 # HG changeset patch # User Durham Goode # Date 1389735496 28800 # Tue Jan 14 13:38:16 2014 -0800 # Node ID c7652078e0d4e1880fce51405cf44c2869edbed7 # Parent 9c531e73a03eb7ddd809da0778d98612ae41134e cat: increase perf when catting single files Special case the single file case in hg cat. This allows us to avoid parsing the manifest, which shaves 15% off hg cat perf. This is worth it, since automation often uses hg cat for retrieving single files. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1157,14 +1157,28 @@ 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() + + # Automation often uses hg cat on single files, so special case it + # for performance to avoid the cost of parsing the manifest. + if len(m.files()) == 1 and not m.anypats(): + file = m.files()[0] + mf = repo.manifest + mfnode = ctx._changeset[0] + if mf.find(mfnode, file)[0]: + write(file) + return 0 + + for abs in ctx.walk(m): + write(abs) err = 0 return err