summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Misc/NEWS.d/next/Library/2023-11-02-12-15-46.gh-issue-111482.FWqZIU.rst3
-rw-r--r--Modules/clinic/timemodule.c.h74
-rw-r--r--Modules/timemodule.c97
3 files changed, 142 insertions, 32 deletions
diff --git a/Misc/NEWS.d/next/Library/2023-11-02-12-15-46.gh-issue-111482.FWqZIU.rst b/Misc/NEWS.d/next/Library/2023-11-02-12-15-46.gh-issue-111482.FWqZIU.rst
new file mode 100644
index 0000000..d73e45c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-11-02-12-15-46.gh-issue-111482.FWqZIU.rst
@@ -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.
diff --git a/Modules/clinic/timemodule.c.h b/Modules/clinic/timemodule.c.h
new file mode 100644
index 0000000..bbc0748
--- /dev/null
+++ b/Modules/clinic/timemodule.c.h
@@ -0,0 +1,74 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+#if defined(HAVE_CLOCK_GETTIME)
+
+PyDoc_STRVAR(time_clock_gettime__doc__,
+"clock_gettime($module, clk_id, /)\n"
+"--\n"
+"\n"
+"Return the time of the specified clock clk_id as a float.");
+
+#define TIME_CLOCK_GETTIME_METHODDEF \
+ {"clock_gettime", (PyCFunction)time_clock_gettime, METH_O, time_clock_gettime__doc__},
+
+static PyObject *
+time_clock_gettime_impl(PyObject *module, clockid_t clk_id);
+
+static PyObject *
+time_clock_gettime(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ clockid_t clk_id;
+
+ if (!time_clockid_converter(arg, &clk_id)) {
+ goto exit;
+ }
+ return_value = time_clock_gettime_impl(module, clk_id);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(HAVE_CLOCK_GETTIME) */
+
+#if defined(HAVE_CLOCK_GETTIME)
+
+PyDoc_STRVAR(time_clock_gettime_ns__doc__,
+"clock_gettime_ns($module, clk_id, /)\n"
+"--\n"
+"\n"
+"Return the time of the specified clock clk_id as nanoseconds (int).");
+
+#define TIME_CLOCK_GETTIME_NS_METHODDEF \
+ {"clock_gettime_ns", (PyCFunction)time_clock_gettime_ns, METH_O, time_clock_gettime_ns__doc__},
+
+static PyObject *
+time_clock_gettime_ns_impl(PyObject *module, clockid_t clk_id);
+
+static PyObject *
+time_clock_gettime_ns(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ clockid_t clk_id;
+
+ if (!time_clockid_converter(arg, &clk_id)) {
+ goto exit;
+ }
+ return_value = time_clock_gettime_ns_impl(module, clk_id);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(HAVE_CLOCK_GETTIME) */
+
+#ifndef TIME_CLOCK_GETTIME_METHODDEF
+ #define TIME_CLOCK_GETTIME_METHODDEF
+#endif /* !defined(TIME_CLOCK_GETTIME_METHODDEF) */
+
+#ifndef TIME_CLOCK_GETTIME_NS_METHODDEF
+ #define TIME_CLOCK_GETTIME_NS_METHODDEF
+#endif /* !defined(TIME_CLOCK_GETTIME_NS_METHODDEF) */
+/*[clinic end generated code: output=b589a2132aa9df47 input=a9049054013a1b77]*/
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index bf48c89..e82f6eb 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -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)
@@ -227,23 +233,52 @@ _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;
@@ -251,38 +286,32 @@ time_clock_gettime(PyObject *self, PyObject *args)
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
@@ -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},