##// END OF EJS Templates
parsers: inline fields of dirstate values in C version...
parsers: inline fields of dirstate values in C version Previously, while unpacking the dirstate we'd create 3-4 new CPython objects for most dirstate values: - the state is a single character string, which is pooled by CPython - the mode is a new object if it isn't 0 due to being in the lookup set - the size is a new object if it is greater than 255 - the mtime is a new object if it isn't -1 due to being in the lookup set - the tuple to contain them all In some cases such as regular hg status, we actually look at all the objects. In other cases like hg add, hg status for a subdirectory, or hg status with the third-party hgwatchman enabled, we look at almost none of the objects. This patch eliminates most object creation in these cases by defining a custom C struct that is exposed to Python with an interface similar to a tuple. Only when tuple elements are actually requested are the respective objects created. The gains, where they're expected, are significant. The following tests are run against a working copy with over 270,000 files. parse_dirstate becomes significantly faster: $ hg perfdirstate before: wall 0.186437 comb 0.180000 user 0.160000 sys 0.020000 (best of 35) after: wall 0.093158 comb 0.100000 user 0.090000 sys 0.010000 (best of 95) and as a result, several commands benefit: $ time hg status # with hgwatchman enabled before: 0.42s user 0.14s system 99% cpu 0.563 total after: 0.34s user 0.12s system 99% cpu 0.471 total $ time hg add new-file before: 0.85s user 0.18s system 99% cpu 1.033 total after: 0.76s user 0.17s system 99% cpu 0.931 total There is a slight regression in regular status performance, but this is fixed in an upcoming patch.

File last commit:

r18772:0bba1ff2 default
r21809:e250b830 default
Show More
map
269 lines | 11.8 KiB | text/plain | TextLexer
default = 'summary'
mimetype = 'text/html; charset={encoding}'
header = header.tmpl
footer = footer.tmpl
search = search.tmpl
changelog = changelog.tmpl
summary = summary.tmpl
error = error.tmpl
notfound = notfound.tmpl
help = help.tmpl
helptopics = helptopics.tmpl
helpentry = '
<tr><td>
<a href="{url|urlescape}help/{topic|escape}{sessionvars%urlparameter}">
{topic|escape}
</a>
</td><td>
{summary|escape}
</td></tr>'
naventry = '<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
navshortentry = '<a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
navgraphentry = '<a href="{url|urlescape}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
filenaventry = '<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a>'
filedifflink = '<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
filenodelink = '
<tr class="parity{parity}">
<td><a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
<td></td>
<td>
<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
<a href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
</td>
</tr>'
filenolink = '
<tr class="parity{parity}">
<td><a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
<td></td>
<td>
file |
annotate |
<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
<a href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
</td>
</tr>'
nav = '{before%naventry} {after%naventry}'
navshort = '{before%navshortentry}{after%navshortentry}'
navgraph = '{before%navgraphentry}{after%navgraphentry}'
filenav = '{before%filenaventry}{after%filenaventry}'
fileellipses = '...'
changelogentry = changelogentry.tmpl
searchentry = changelogentry.tmpl
changeset = changeset.tmpl
manifest = manifest.tmpl
direntry = '
<tr class="parity{parity}">
<td>drwxr-xr-x</td>
<td></td>
<td></td>
<td><a href="{url|urlescape}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
<td><a href="{url|urlescape}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></td>
</tr>'
fileentry = '
<tr class="parity{parity}">
<td>{permissions|permissions}</td>
<td>{date|isodate}</td>
<td>{size}</td>
<td><a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
<td>
<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
</td>
</tr>'
filerevision = filerevision.tmpl
fileannotate = fileannotate.tmpl
filediff = filediff.tmpl
filecomparison = filecomparison.tmpl
filelog = filelog.tmpl
fileline = '
<div style="font-family:monospace" class="parity{parity}">
<pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</pre>
</div>'
annotateline = '
<tr class="parity{parity}">
<td class="linenr">
<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
</td>
<td class="lineno">
<a href="#{lineid}" id="{lineid}">{linenumber}</a>
</td>
<td class="source">{line|escape}</td>
</tr>'
difflineplus = '<span style="color:#008800;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
difflineat = '<span style="color:#990099;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
diffline = '<span><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
comparisonblock ='
<tbody class="block">
{lines}
</tbody>'
comparisonline = '
<tr>
<td class="source {type}"><a class="linenr" href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
<td class="source {type}"><a class="linenr" href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
</tr>'
changelogparent = '
<tr>
<th class="parent">parent {rev}:</th>
<td class="parent">
<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
</td>
</tr>'
changesetbranch = '<dt>branch</dt><dd>{name|escape}</dd>'
changesetparent = '
<dt>parent {rev}</dt>
<dd><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
filerevbranch = '<dt>branch</dt><dd>{name|escape}</dd>'
filerevparent = '
<dt>parent {rev}</dt>
<dd>
<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
{rename%filerename}{node|short}
</a>
</dd>'
filerename = '{file|escape}@'
filelogrename = '| <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
fileannotateparent = '
<dt>parent {rev}</dt>
<dd>
<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
{rename%filerename}{node|short}
</a>
</dd>'
changelogchild = '
<dt>child {rev}:</dt>
<dd><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
changesetchild = '
<dt>child {rev}</dt>
<dd><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
filerevchild = '
<dt>child {rev}</dt>
<dd>
<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
</dd>'
fileannotatechild = '
<dt>child {rev}</dt>
<dd>
<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
</dd>'
tags = tags.tmpl
tagentry = '
<tr class="parity{parity}">
<td class="nowrap age">{date|rfc822date}</td>
<td><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td>
<td class="nowrap">
<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
<a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
</td>
</tr>'
bookmarks = bookmarks.tmpl
bookmarkentry = '
<tr class="parity{parity}">
<td class="nowrap date">{date|rfc822date}</td>
<td><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{bookmark|escape}</a></td>
<td class="nowrap">
<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
<a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
</td>
</tr>'
branches = branches.tmpl
branchentry = '
<tr class="parity{parity}">
<td class="nowrap age">{date|rfc822date}</td>
<td><a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
<td class="{status}">{branch|escape}</td>
<td class="nowrap">
<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
<a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
</td>
</tr>'
diffblock = '<pre>{lines}</pre>'
filediffparent = '
<dt>parent {rev}</dt>
<dd><a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
filecompparent = '
<dt>parent {rev}</dt>
<dd><a href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
filelogparent = '
<tr>
<td align="right">parent {rev}:&nbsp;</td>
<td><a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
</tr>'
filediffchild = '
<dt>child {rev}</dt>
<dd><a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
filecompchild = '
<dt>child {rev}</dt>
<dd><a href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
filelogchild = '
<tr>
<td align="right">child {rev}:&nbsp;</td>
<td><a href="{url|urlescape}file{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
</tr>'
shortlog = shortlog.tmpl
tagtag = '<span class="tagtag" title="{name|escape}">{name|escape}</span> '
branchtag = '<span class="branchtag" title="{name|escape}">{name|escape}</span> '
inbranchtag = '<span class="inbranchtag" title="{name|escape}">{name|escape}</span> '
bookmarktag = '<span class="bookmarktag" title="{name|escape}">{name|escape}</span> '
shortlogentry = '
<tr class="parity{parity}">
<td class="nowrap age">{date|rfc822date}</td>
<td>{author|person}</td>
<td>
<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
{desc|strip|firstline|escape|nonempty}
<span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
</a>
</td>
<td class="nowrap">
<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
<a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
</td>
</tr>'
filelogentry = '
<tr class="parity{parity}">
<td class="nowrap age">{date|rfc822date}</td>
<td><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td>
<td class="nowrap">
<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
{rename%filelogrename}
</td>
</tr>'
archiveentry = '<li><a href="{url|urlescape}archive/{node|short}{extension}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a></li>'
indexentry = '
<tr class="parity{parity}">
<td><a href="{url|urlescape}{sessionvars%urlparameter}">{name|escape}</a></td>
<td>{description}</td>
<td>{contact|obfuscate}</td>
<td class="age">{lastchange|rfc822date}</td>
<td class="indexlinks">{archives%indexarchiveentry}</td>
<td>
{if(isdirectory, '',
'<div class="rss_logo">
<a href="{url|urlescape}rss-log">RSS</a> <a href="{url|urlescape}atom-log">Atom</a>
</div>'
)}
</td>
</tr>\n'
indexarchiveentry = '<a href="{url|urlescape}archive/{node|short}{extension}">{type|escape}</a> '
index = index.tmpl
urlparameter = '{separator}{name}={value|urlescape}'
hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
graph = graph.tmpl
breadcrumb = '&gt; <a href="{url|urlescape}">{name|escape}</a> '