# HG changeset patch # User Gregory Szorc # Date 1490324099 25200 # Node ID ed5b25874d998ababb181a939dd37a16ea644435 # Parent 2915cc1d3429f9b11c9cf48d45990f982fff8e7a changegroup: store old heads as a set Previously, the "oldheads" variable was a list. On a repository at Mozilla with 46,492 heads, profiling revealed that list membership testing was dominating execution time of applying small changegroups. This patch converts the list of old heads to a set. This makes membership testing significantly faster. On the aforementioned repository with 46,492 heads: $ hg unbundle before: 18.535s wall after: 1.303s Consumers of this variable only check for truthiness (`if oldheads`), length (`len(oldheads)`), and (most importantly) item membership (`h not in oldheads` - which occurs twice). So, the change to a set should be safe and suitable for stable. The practical effect of this change is that changegroup application and related operations (like `hg push`) no longer exhibit an O(n^2) CPU explosion as the number of heads grows. diff -r 2915cc1d3429 -r ed5b25874d99 mercurial/changegroup.py --- a/mercurial/changegroup.py Mon Mar 20 04:36:55 2017 -0700 +++ b/mercurial/changegroup.py Thu Mar 23 19:54:59 2017 -0700 @@ -293,7 +293,7 @@ # will not see an inconsistent view cl = repo.changelog cl.delayupdate(tr) - oldheads = cl.heads() + oldheads = set(cl.heads()) trp = weakref.proxy(tr) # pull off the changeset group