comparison mercurial/scmutil.py @ 16390:4df76d5506a9

scmutil: speed up revrange This improves the performance of "hg log -l1" from 0.21 seconds to 0.07 on a Linux kernel tree. Ideally we could use xrange instead of range on the most common path, and thus avoid a ton of allocation, but xrange doesn't support slice-based indexing.
author Bryan O'Sullivan <bryano@fb.com>
date Mon, 09 Apr 2012 22:16:26 -0700
parents f5dd179bfa4a
children e98460f6089d
comparison
equal deleted inserted replaced
16389:79fecd735d26 16390:4df76d5506a9
532 return defval 532 return defval
533 return repo[val].rev() 533 return repo[val].rev()
534 534
535 seen, l = set(), [] 535 seen, l = set(), []
536 for spec in revs: 536 for spec in revs:
537 if l and not seen:
538 seen = set(l)
537 # attempt to parse old-style ranges first to deal with 539 # attempt to parse old-style ranges first to deal with
538 # things like old-tag which contain query metacharacters 540 # things like old-tag which contain query metacharacters
539 try: 541 try:
540 if isinstance(spec, int): 542 if isinstance(spec, int):
541 seen.add(spec) 543 seen.add(spec)
545 if _revrangesep in spec: 547 if _revrangesep in spec:
546 start, end = spec.split(_revrangesep, 1) 548 start, end = spec.split(_revrangesep, 1)
547 start = revfix(repo, start, 0) 549 start = revfix(repo, start, 0)
548 end = revfix(repo, end, len(repo) - 1) 550 end = revfix(repo, end, len(repo) - 1)
549 step = start > end and -1 or 1 551 step = start > end and -1 or 1
550 for rev in xrange(start, end + step, step): 552 if not seen and not l:
551 if rev in seen: 553 # by far the most common case: revs = ["-1:0"]
552 continue 554 l = range(start, end + step, step)
553 seen.add(rev) 555 # defer syncing seen until next iteration
554 l.append(rev) 556 continue
557 newrevs = set(xrange(start, end + step, step))
558 if seen:
559 newrevs.difference_update(seen)
560 seen.union(newrevs)
561 else:
562 seen = newrevs
563 l.extend(sorted(newrevs, reverse=start > end))
555 continue 564 continue
556 elif spec and spec in repo: # single unquoted rev 565 elif spec and spec in repo: # single unquoted rev
557 rev = revfix(repo, spec, None) 566 rev = revfix(repo, spec, None)
558 if rev in seen: 567 if rev in seen:
559 continue 568 continue