Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:mod:`time`: Make :func:`time.clock_gettime()` and
:func:`time.clock_gettime_ns()` functions up to 2x faster by faster calling
convention. Patch by Victor Stinner.
74 changes: 74 additions & 0 deletions Modules/clinic/timemodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 65 additions & 32 deletions Modules/timemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@
#define SEC_TO_NS (1000 * 1000 * 1000)


/*[clinic input]
module time
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a668a08771581f36]*/


#if defined(HAVE_TIMES) || defined(HAVE_CLOCK)
static int
check_ticks_per_second(long tps, const char *context)
Expand Down Expand Up @@ -227,62 +233,85 @@ _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
#pragma clang diagnostic ignored "-Wunguarded-availability"
#endif

static PyObject *
time_clock_gettime(PyObject *self, PyObject *args)
static int
time_clockid_converter(PyObject *obj, clockid_t *p)
{
int ret;
struct timespec tp;

#if defined(_AIX) && (SIZEOF_LONG == 8)
long clk_id;
if (!PyArg_ParseTuple(args, "l:clock_gettime", &clk_id)) {
long clk_id = PyLong_AsLong(obj);
#else
int clk_id;
if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
int clk_id = PyLong_AsInt(obj);
#endif
return NULL;
if (clk_id == -1 && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError,
"clk_id should be integer, not %s",
_PyType_Name(Py_TYPE(obj)));
return 0;
}

ret = clock_gettime((clockid_t)clk_id, &tp);
// Make sure that we picked the right type (check sizes type)
Py_BUILD_ASSERT(sizeof(clk_id) == sizeof(*p));
*p = (clockid_t)clk_id;
return 1;
}

/*[python input]

class clockid_t_converter(CConverter):
type = "clockid_t"
converter = 'time_clockid_converter'

[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=53867111501f46c8]*/


/*[clinic input]
time.clock_gettime

clk_id: clockid_t
/

Return the time of the specified clock clk_id as a float.
[clinic start generated code]*/

static PyObject *
time_clock_gettime_impl(PyObject *module, clockid_t clk_id)
/*[clinic end generated code: output=832b9ebc03328020 input=7e89fcc42ca15e5d]*/
{
struct timespec tp;
int ret = clock_gettime(clk_id, &tp);
if (ret != 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
}

PyDoc_STRVAR(clock_gettime_doc,
"clock_gettime(clk_id) -> float\n\
\n\
Return the time of the specified clock clk_id.");
/*[clinic input]
time.clock_gettime_ns

clk_id: clockid_t
/

Return the time of the specified clock clk_id as nanoseconds (int).
[clinic start generated code]*/

static PyObject *
time_clock_gettime_ns(PyObject *self, PyObject *args)
time_clock_gettime_ns_impl(PyObject *module, clockid_t clk_id)
/*[clinic end generated code: output=4a045c3a36e60044 input=aabc248db8c8e3e5]*/
{
int ret;
int clk_id;
struct timespec ts;
_PyTime_t t;

if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
return NULL;
}

ret = clock_gettime((clockid_t)clk_id, &ts);
int ret = clock_gettime(clk_id, &ts);
if (ret != 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}

_PyTime_t t;
if (_PyTime_FromTimespec(&t, &ts) < 0) {
return NULL;
}
return _PyTime_AsNanosecondsObject(t);
}

PyDoc_STRVAR(clock_gettime_ns_doc,
"clock_gettime_ns(clk_id) -> int\n\
\n\
Return the time of the specified clock clk_id as nanoseconds.");
#endif /* HAVE_CLOCK_GETTIME */

#ifdef HAVE_CLOCK_SETTIME
Expand Down Expand Up @@ -1857,12 +1886,16 @@ init_timezone(PyObject *m)
}


// Include Argument Clinic code after defining converters such as
// time_clockid_converter().
#include "clinic/timemodule.c.h"

static PyMethodDef time_methods[] = {
{"time", time_time, METH_NOARGS, time_doc},
{"time_ns", time_time_ns, METH_NOARGS, time_ns_doc},
#ifdef HAVE_CLOCK_GETTIME
{"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc},
{"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc},
TIME_CLOCK_GETTIME_METHODDEF
TIME_CLOCK_GETTIME_NS_METHODDEF
#endif
#ifdef HAVE_CLOCK_SETTIME
{"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc},
Expand Down