diff -r 9dd59c32e7f0 Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Wed Jan 13 17:08:33 2016 +0100 +++ b/Modules/_testcapimodule.c Wed Jan 13 17:09:19 2016 +0100 @@ -3584,6 +3584,49 @@ dict_set_version(PyObject *self, PyObjec Py_RETURN_NONE; } +static PyObject * +guard_benchmark(PyObject *self, PyObject *args) +{ + _PyTime_t before, after, dt, best; + Py_ssize_t run, nrun = 100, loop, nloop = 10 * 1000 * 1000; + PyObject *dict, *key; + PyFuncGuardObject *guard; + + if (!PyArg_ParseTuple(args, "O!O!O!", + &PyDict_Type, &dict, + &PyUnicode_Type, &key, + &PyFuncGuard_Type, &guard)) + return NULL; + + best = 0; + for (run=0; run < nrun; run++) { + before = _PyTime_GetMonotonicClock(); + for (loop=0; loopcheck((PyObject *)guard, NULL, 0, 0); + if (res) + return NULL; +#endif + } + after = _PyTime_GetMonotonicClock(); + + dt = after - before; + if (best == 0 || dt < best) + best = dt; + } + + return PyFloat_FromDouble(_PyTime_AsSecondsDouble(best) / nloop); +} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, @@ -3763,6 +3806,7 @@ static PyMethodDef TestMethods[] = { {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, {"dict_get_version", dict_get_version, METH_VARARGS}, {"dict_set_version", dict_set_version, METH_VARARGS}, + {"guard_benchmark", guard_benchmark, METH_VARARGS}, {NULL, NULL} /* sentinel */ };