ANN: hg graphlog extension
Alexis S. L. Carvalho
alexis at cecm.usp.br
Sun Apr 8 07:26:59 UTC 2007
Thus spake Joel Rosdahl:
> Done. Current performance in the linux-2.6 repo on my box:
>
> hg glog -q > /dev/null # --> 8.0 seconds
> hg log -q > /dev/null # --> 4.1 seconds
Turns out that glog was hitting a performance buglet in revlog.py.
After fixing it (changeset 43dedce9667e), in my (not up to date) kernel
repo, the time goes from ~6.9s to ~6.3s (log -q is still around 3.8s).
The patch below changes revision_grapher to walk the changeset graph
using revision numbers instead of nodes - this is usually a bit faster,
since the graph is stored using numbers, not nodes. The running time
goes to ~5.6s.
Alexis
# HG changeset patch
# User Alexis S. L. Carvalho <alexis at cecm.usp.br>
# Date 1176016277 10800
# Node ID 6fdbc3df86cceac27e8838c0518a20d89d427ae8
# Parent 8d0bbc825ac0a46a550cab519d80c91c737e3884
Walk the changeset graph using revision numbers, not nodes.
diff -r 8d0bbc825ac0 -r 6fdbc3df86cc graphlog.py
--- a/graphlog.py Sun Apr 08 04:02:49 2007 -0300
+++ b/graphlog.py Sun Apr 08 04:11:17 2007 -0300
@@ -45,42 +45,42 @@ def revision_grapher(repo, start_rev, st
assert start_rev >= stop_rev
rev = start_rev
- nodes = []
+ revs = []
while rev >= stop_rev:
node = repo.changelog.node(rev)
# Compute nodes and next nodes.
- if node not in nodes:
- # New head node.
- nodes.append(node)
- node_index = nodes.index(node)
- next_nodes = nodes[:]
-
- # Add parents to next nodes.
- parents = get_node_parents(repo, node)
+ if rev not in revs:
+ # New head rev.
+ revs.append(rev)
+ rev_index = revs.index(rev)
+ next_revs = revs[:]
+
+ # Add parents to next revs.
+ parents = get_rev_parents(repo, rev)
parents_to_add = []
for parent in parents:
- if parent not in next_nodes:
+ if parent not in next_revs:
parents_to_add.append(parent)
if len(parents_to_add) == 0:
- del next_nodes[node_index]
- else:
- next_nodes[node_index] = parents_to_add[0]
+ del next_revs[rev_index]
+ else:
+ next_revs[rev_index] = parents_to_add[0]
if len(parents_to_add) == 2:
- next_nodes.insert(node_index, parents_to_add[1])
+ next_revs.insert(rev_index, parents_to_add[1])
edges = []
for parent in parents:
- edges.append((node_index, next_nodes.index(parent)))
-
- n_nodes_diff = len(next_nodes) - len(nodes)
- yield (rev, node, node_index, edges, len(nodes), n_nodes_diff)
-
- nodes = next_nodes
+ edges.append((rev_index, next_revs.index(parent)))
+
+ n_revs_diff = len(next_revs) - len(revs)
+ yield (rev, node, rev_index, edges, len(revs), n_revs_diff)
+
+ revs = next_revs
rev -= 1
-def get_node_parents(repo, node):
- return [x for x in repo.changelog.parents(node) if x != nullid]
+def get_rev_parents(repo, rev):
+ return [x for x in repo.changelog.parentrevs(rev) if x != nullrev]
def fix_cross_edge(edges):
for (i, (start, end)) in enumerate(edges):
More information about the Mercurial
mailing list