diff --git a/benchmarks/utils.py b/benchmarks/utils.py index 6e5e0052cacded9ae92ff8110f8baa2b8609fb8a_YmVuY2htYXJrcy91dGlscy5weQ==..734c303027274fcd4aa33692c60791d2ca2c66d6_YmVuY2htYXJrcy91dGlscy5weQ== 100644 --- a/benchmarks/utils.py +++ b/benchmarks/utils.py @@ -1,2 +1,5 @@ from __future__ import print_function +import errno +import functools +import hashlib import json @@ -2,4 +5,3 @@ import json -import functools import os import os.path @@ -4,3 +6,4 @@ import os import os.path +import pickle import re @@ -6,4 +9,3 @@ import re -import timeit import subprocess import sys @@ -8,5 +10,6 @@ import subprocess import sys +import timeit from functools import wraps REPO_SUFFIX='.benchrepo' @@ -281,6 +284,46 @@ localdata['maximum'] = item['max.wall'] return result + def getperfdata(self, key, cmd): + """Retrieve performance data from running cmd + + The result is cached to avoid running the same benchmark multiple time. + Use this to handle commands from the perf extensions that returns + multiple values.""" + key = (repr(self.__class__), self.get_asv_rev(), self.repo_name) + key + + try: + return self._get_cache(key) + except KeyError: + data = self.perfextjson(*cmd) + self._set_cache(key, data) + return data + + def _cache_file(self, key): + filename = hashlib.sha256(repr(key)).hexdigest() + return os.path.join(self._cache_dir, 'perf-cache', filename) + + def _set_cache(self, key, data): + cachefile = self._cache_file(key) + cachedir = os.path.dirname(cachefile) + if not os.path.isdir(cachedir): + os.mkdir(cachedir) + with open(cachefile, 'wb') as f: + pickle.dump(data, f) + + def _get_cache(self, key): + cachefile = self._cache_file(key) + try: + with open(cachefile, 'rb') as f: + return pickle.load(f) + except IOError as exc: + if not exc.errno == errno.ENOENT: + raise + raise KeyError(key) + + def setup_cache(self): + self._cache_dir = os.getcwd() + def setup(self, repo, *args, **kwargs): venv = os.path.abspath(os.path.join(os.path.dirname(sys.executable), "..")) self.repo_name = repo @@ -302,6 +345,8 @@ for key in ('SSH_AUTH_SOCK',): if key in os.environ: self.environ[key] = os.environ[key] + # define the cache dir for simplicity + self._cache_dir = os.getcwd() def teardown(self, *args, **kwargs): # only here for consintency and ease; you can use super().teardown()