Patchwork [V2] revset: improve head revset performance

login
register
mail settings
Submitter Durham Goode
Date March 13, 2014, 9:48 p.m.
Message ID <ee115a100278ac12cc4f.1394747290@dev2000.prn2.facebook.com>
Download mbox | patch
Permalink /patch/3944/
State Accepted
Commit 6a1a4c212d50b761c9abffabbd988d68aa95f607
Headers show

Comments

Durham Goode - March 13, 2014, 9:48 p.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1394743641 25200
#      Thu Mar 13 13:47:21 2014 -0700
# Node ID ee115a100278ac12cc4fd712f536518fa78e009b
# Parent  1cd5bff45db28150d7c140be493fe851e6560f27
revset: improve head revset performance

Previously the head() revset would iterate over every item in the subset and
check if it was a head.  Since the subset is often the entire repo, this was
slow on large repos. Now we iterate over each item in the head list and check if
it's in the subset, which results in much less work.

hg log -r 'head()' on a large repo:
Before: 0.95s
After: 0.28s
Matt Mackall - March 13, 2014, 9:50 p.m.
On Thu, 2014-03-13 at 14:48 -0700, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham@fb.com>
> # Date 1394743641 25200
> #      Thu Mar 13 13:47:21 2014 -0700
> # Node ID ee115a100278ac12cc4fd712f536518fa78e009b
> # Parent  1cd5bff45db28150d7c140be493fe851e6560f27
> revset: improve head revset performance
> 
> Previously the head() revset would iterate over every item in the subset and
> check if it was a head.  Since the subset is often the entire repo, this was
> slow on large repos. Now we iterate over each item in the head list and check if
> it's in the subset, which results in much less work.
> 
> hg log -r 'head()' on a large repo:
> Before: 0.95s
> After: 0.28s

Shiny, queued for default.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -941,7 +941,7 @@ 
     hs = set()
     for b, ls in repo.branchmap().iteritems():
         hs.update(repo[h].rev() for h in ls)
-    return subset.filter(lambda r: r in hs)
+    return baseset(hs).filter(subset.__contains__)
 
 def heads(repo, subset, x):
     """``heads(set)``