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()