Skip to content
Snippets Groups Projects
Commit 4c7a7f5c authored by Pierre-Yves David's avatar Pierre-Yves David :octopus:
Browse files

perf: introduce a benchmark method based on Mercurial perf extension

This will allow us to reuse a lot of work that already exist in Mercurial.
parent a36caf3a
No related branches found
No related tags found
1 merge request!13bunch of new things.
......@@ -3,7 +3,12 @@
import subprocess
import tempfile
import time
import poulpe
from . import basics as poulpe
class UnknownBenchmarkMethod(KeyError):
pass
def run_one(bin_env_path, data_env_path, benchmark_path, result):
......@@ -57,7 +62,11 @@
data = poulpe.get_data(path)
if data is None:
return None
return SimpleCommandBenchmark(data, variants)
method = data.get('meta', {}).get('method')
if method == 'simple-command':
return SimpleCommandBenchmark(data, variants)
elif method == 'mercurial-perf-extension':
return PerfBenchmark(data, variants)
class Benchmark:
......@@ -66,7 +75,6 @@
self._raw_data = data
assert self._raw_data['meta']['format'] == "0"
assert self._raw_data['meta']['method'] == "simple-command"
self._data = self._raw_data.copy()
if variants is None:
......@@ -99,6 +107,8 @@
def __init__(self, data, variants=None):
super().__init__(data, variants)
assert self._raw_data['meta']['method'] == "simple-command"
for dimension, variants in self.all_dimensions.items():
# find the variants we should use.
selected = self._selected_variants.get(dimension)
......@@ -218,3 +228,88 @@
with open(tmp_result.name) as f:
return json.load(f)
class PerfBenchmark(Benchmark):
"""A benchmark that use the Mercurial performance extension
It assumes an up to date mercurial repository live in
The path to the perf extension should be contained in the HGPERFPATH
environment variable.
bin-env-dir/../repos/mercurial/
(This might live in a pluging in the future.)
"""
def run_one(self, bin_env_path, data_env_path):
bin_env_path = os.path.abspath(bin_env_path)
data_env_path = os.path.abspath(data_env_path)
shell_path = poulpe.bin_env_script(bin_env_path)
perf_command = self.get_var('hg-perf-ext.command')
if 'HG_PERF_PATH' not in os.environ:
msg = "missing environment variable HG_PERF_PATH"
raise RuntimeError(msg)
perf_ext_path = os.environ['HG_PERF_PATH']
if not os.path.exists(perf_ext_path):
msg = 'could not find perf extension at: %s'
raise RuntimeError(msg % perf_ext_path)
cwd = data_env_path
cfg_cwd = self.get_var('hg-perf-ext.cwd')
if cfg_cwd is not None:
if cfg_cwd.startswith('DATA-VARS:'):
data_env_desc = poulpe.data_env_file(data_env_path)
data_env_data = poulpe.get_data(data_env_desc)
key = cfg_cwd.split(':', 1)[1]
full_key = f'bench-input-vars.{key}'
cfg_cwd = poulpe.get_one_value(data_env_data, full_key)
cwd = os.path.join(cwd, cfg_cwd)
cmd = [
shell_path,
'hg',
'--config',
f'extensions.perf={perf_ext_path}',
'--config',
'perf.all-timing=yes',
perf_command,
'--template',
'json'
]
r = subprocess.run(
cmd,
cwd=cwd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
assert r.returncode == 0, r.stderr
data = json.loads(r.stderr)
res = {}
# XXX wall/sys/user/comb should probably be a sub-layer in 'time'
# XXX note that the perf extension does not provides any "min"
res['time'] = {}
res['time']['mean'] = data[0]['avg.wall']
res['time']['median'] = data[0]['median.wall']
res['time']['max'] = data[0]['max.wall']
res['sys-time'] = {}
res['sys-time']['mean'] = data[0]['avg.sys']
res['sys-time']['median'] = data[0]['median.sys']
res['sys-time']['max'] = data[0]['max.sys']
res['user-time'] = {}
res['user-time']['mean'] = data[0]['avg.user']
res['user-time']['median'] = data[0]['median.user']
res['user-time']['max'] = data[0]['max.user']
res['comb-time'] = {}
res['comb-time']['mean'] = data[0]['avg.comb']
res['comb-time']['median'] = data[0]['median.comb']
res['comb-time']['max'] = data[0]['max.comb']
res['run-count'] = data[0]['count']
return res
[meta]
format="0"
name="perf-startup"
method="mercurial-perf-extension"
[hg-perf-ext]
command="perf::startup"
cwd="DATA-VARS:mercurial.main-repo-path"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment