comparison contrib/perf.py @ 16414:e8d37b78acfb

parsers: use base-16 trie for faster node->rev mapping This greatly speeds up node->rev lookups, with results that are often user-perceptible: for instance, "hg --time log" of the node associated with rev 1000 on a linux-2.6 repo improves from 0.3 seconds to 0.03. I have not found any instances of slowdowns. The new perfnodelookup command in contrib/perf.py demonstrates the speedup more dramatically, since it performs no I/O. For a single lookup, the new code is about 40x faster. These changes also prepare the ground for the possibility of further improving the performance of prefix-based node lookups.
author Bryan O'Sullivan <bryano@fb.com>
date Thu, 12 Apr 2012 14:05:59 -0700
parents efae1fea4bbd
children 525fdb738975
comparison
equal deleted inserted replaced
16413:1a420761fcb7 16414:e8d37b78acfb
1 # perf.py - performance test routines 1 # perf.py - performance test routines
2 '''helper extension to measure performance''' 2 '''helper extension to measure performance'''
3 3
4 from mercurial import cmdutil, scmutil, match, commands 4 from mercurial import cmdutil, scmutil, util, match, commands
5 import time, os, sys 5 import time, os, sys
6 6
7 def timer(func, title=None): 7 def timer(func, title=None):
8 results = [] 8 results = []
9 begin = time.time() 9 begin = time.time()
116 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg 116 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
117 n = repo[rev].node() 117 n = repo[rev].node()
118 def d(): 118 def d():
119 cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i") 119 cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i")
120 cl.rev(n) 120 cl.rev(n)
121 timer(d)
122
123 def perfnodelookup(ui, repo, rev):
124 import mercurial.revlog
125 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
126 n = repo[rev].node()
127 cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i")
128 # behave somewhat consistently across internal API changes
129 if util.safehasattr(cl, 'clearcaches'):
130 clearcaches = cl.clearcaches
131 elif util.safehasattr(cl, '_nodecache'):
132 from mercurial.node import nullid, nullrev
133 def clearcaches():
134 cl._nodecache = {nullid: nullrev}
135 cl._nodepos = None
136 else:
137 def clearcaches():
138 pass
139 def d():
140 cl.rev(n)
141 clearcaches()
121 timer(d) 142 timer(d)
122 143
123 def perflog(ui, repo, **opts): 144 def perflog(ui, repo, **opts):
124 ui.pushbuffer() 145 ui.pushbuffer()
125 timer(lambda: commands.log(ui, repo, rev=[], date='', user='', 146 timer(lambda: commands.log(ui, repo, rev=[], date='', user='',