Patchwork [5,of,6,RFC] perf: introduce function to choose appropriate object to access files

login
register
mail settings
Submitter Katsunori FUJIWARA
Date June 10, 2016, 7:20 p.m.
Message ID <b5487e8e3142fc650b5f.1465586419@feefifofum>
Download mbox | patch
Permalink /patch/15467/
State Changes Requested
Headers show

Comments

Katsunori FUJIWARA - June 10, 2016, 7:20 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1465585986 -32400
#      Sat Jun 11 04:13:06 2016 +0900
# Node ID b5487e8e3142fc650b5fa3d0fbe3e8ff4e24da3e
# Parent  9f50ea27207df58c0a520392b3a052b55dbf5b37
perf: introduce function to choose appropriate object to access files

Before this patch, using svfs prevents perf.py from measuring
performance of Mercurial earlier than 2.3 (or 7034365089bf), because
svfs isn't available in such Mercurial, even though there are some
code paths for Mercurial earlier than 2.3.

For example, setting "_prereadsize" attribute in perfindex() and
perfnodelookup() is effective only with hg earlier than 1.8 (or
61c9bc3da402).

To choose appropriate object to access files under .hg/store, this
patch introduces getsvfs() (and also getvfs(), for future use).

To avoid examining existence of attribute at each repetition,
getsvfs() is invoked outside the function to be called repeatedly.

This patch also adds check-code.py new "perf.py" check entry, to
detect direct usage of repo.(vfs|svfs|opener|sopener) in perf.py.

Patch

diff --git a/contrib/check-code.py b/contrib/check-code.py
--- a/contrib/check-code.py
+++ b/contrib/check-code.py
@@ -421,6 +421,15 @@  webtemplatepats = [
   ]
 ]
 
+perfpypats = [
+  [
+    (r'\.(vfs|svfs|opener|sopener)',
+     "use getvfs()/getsvfs() for early Mercurial"),
+  ],
+  # warnings
+  []
+]
+
 checks = [
     ('python', r'.*\.(py|cgi)$', r'^#!.*python', pyfilters, pypats),
     ('test script', r'(.*/)?test-[^.~]*$', '', testfilters, testpats),
@@ -433,6 +442,7 @@  checks = [
     ('txt', r'.*\.txt$', '', txtfilters, txtpats),
     ('web template', r'mercurial/templates/.*\.tmpl', '',
      webtemplatefilters, webtemplatepats),
+    ('perf.py', r'contrib/perf.py$', '', pyfilters, perfpypats),
 ]
 
 def _preparepats():
diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -137,6 +137,22 @@  def _timer(fm, func, title=None):
     fm.write('count',  ' (best of %d)', count)
     fm.plain('\n')
 
+def getvfs(repo):
+    """Return appropriate object to access files under .hg
+    """
+    if util.safehasattr(repo, 'vfs'):
+        return getattr(repo, 'vfs')
+    else:
+        return getattr(repo, 'opener')
+
+def getsvfs(repo):
+    """Return appropriate object to access files under .hg/store
+    """
+    if util.safehasattr(repo, 'svfs'):
+        return getattr(repo, 'svfs')
+    else:
+        return getattr(repo, 'sopener')
+
 @command('perfwalk', formatteropts)
 def perfwalk(ui, repo, *pats, **opts):
     timer, fm = gettimer(ui, opts)
@@ -205,9 +221,10 @@  def perftags(ui, repo, **opts):
     import mercurial.changelog
     import mercurial.manifest
     timer, fm = gettimer(ui, opts)
+    svfs = getsvfs(repo)
     def t():
-        repo.changelog = mercurial.changelog.changelog(repo.svfs)
-        repo.manifest = mercurial.manifest.manifest(repo.svfs)
+        repo.changelog = mercurial.changelog.changelog(svfs)
+        repo.manifest = mercurial.manifest.manifest(svfs)
         repo._tags = None
         return len(repo.tags())
     timer(t)
@@ -355,8 +372,9 @@  def perfindex(ui, repo, **opts):
     timer, fm = gettimer(ui, opts)
     mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
     n = repo["tip"].node()
+    svfs = getsvfs(repo)
     def d():
-        cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
+        cl = mercurial.revlog.revlog(svfs, "00changelog.i")
         cl.rev(n)
     timer(d)
     fm.end()
@@ -428,7 +446,7 @@  def perfnodelookup(ui, repo, rev, **opts
     import mercurial.revlog
     mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
     n = repo[rev].node()
-    cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
+    cl = mercurial.revlog.revlog(getsvfs(repo), "00changelog.i")
     def d():
         cl.rev(n)
         clearcaches(cl)
@@ -763,7 +781,8 @@  def perfloadmarkers(ui, repo):
 
     Result is the number of markers in the repo."""
     timer, fm = gettimer(ui)
-    timer(lambda: len(obsolete.obsstore(repo.svfs)))
+    svfs = getsvfs(repo)
+    timer(lambda: len(obsolete.obsstore(svfs)))
     fm.end()
 
 @command('perflrucachedict', formatteropts +