summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-10-12 15:51:56 (GMT)
committerGitHub <noreply@github.com>2017-10-12 15:51:56 (GMT)
commitcba9a0c6def70549046f1afa6a80e38fe706520e (patch)
tree1700dda3a2a2170cc5d0766387fe6f020540c44c
parent0e61e67a57deb4abc677808201d7cf3c38138e02 (diff)
downloadcpython-cba9a0c6def70549046f1afa6a80e38fe706520e.zip
cpython-cba9a0c6def70549046f1afa6a80e38fe706520e.tar.gz
cpython-cba9a0c6def70549046f1afa6a80e38fe706520e.tar.bz2
bpo-31773: time.perf_counter() uses again double (GH-3964)
time.clock() and time.perf_counter() now use again C double internally. Remove also _PyTime_GetWinPerfCounterWithInfo(): use _PyTime_GetPerfCounterDoubleWithInfo() instead on Windows.
-rw-r--r--Include/pytime.h23
-rw-r--r--Modules/timemodule.c28
-rw-r--r--Python/import.c12
-rw-r--r--Python/pytime.c36
4 files changed, 50 insertions, 49 deletions
diff --git a/Include/pytime.h b/Include/pytime.h
index 95d482f..fd95045 100644
--- a/Include/pytime.h
+++ b/Include/pytime.h
@@ -192,20 +192,21 @@ PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm);
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
-#ifdef MS_WINDOWS
-PyAPI_FUNC(int) _PyTime_GetWinPerfCounterWithInfo(
- _PyTime_t *t,
- _Py_clock_info_t *info);
-#endif
+/* Get the performance counter: clock with the highest available resolution to
+ measure a short duration.
+
+ The function cannot fail. _PyTime_Init() ensures that the system clock
+ works. */
+PyAPI_FUNC(double) _PyTime_GetPerfCounterDouble(void);
/* Get the performance counter: clock with the highest available resolution to
- measure a short duration. */
-PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void);
+ measure a short duration.
-/* Similar to _PyTime_GetPerfCounter(),
- but get also clock info if info is non-NULL. */
-PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo(
- _PyTime_t *t,
+ Fill info (if set) with information of the function used to get the time.
+
+ Return 0 on success, raise an exception and return -1 on error. */
+PyAPI_FUNC(int) _PyTime_GetPerfCounterDoubleWithInfo(
+ double *t,
_Py_clock_info_t *info);
#ifdef __cplusplus
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 2c0a8d6..3cb1b4e 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -88,19 +88,23 @@ floatclock(_Py_clock_info_t *info)
}
#endif /* HAVE_CLOCK */
+static PyObject*
+perf_counter(_Py_clock_info_t *info)
+{
+ double t;
+ if (_PyTime_GetPerfCounterDoubleWithInfo(&t, info) < 0) {
+ return NULL;
+ }
+ return PyFloat_FromDouble(t);
+}
+
#if defined(MS_WINDOWS) || defined(HAVE_CLOCK)
#define PYCLOCK
static PyObject*
pyclock(_Py_clock_info_t *info)
{
#ifdef MS_WINDOWS
- /* Win32 has better clock replacement; we have our own version, due to Mark
- Hammond and Tim Peters */
- _PyTime_t t;
- if (_PyTime_GetWinPerfCounterWithInfo(&t, info) < 0) {
- return NULL;
- }
- return _PyFloat_FromPyTime(t);
+ return perf_counter(info);
#else
return floatclock(info);
#endif
@@ -936,16 +940,6 @@ PyDoc_STRVAR(monotonic_doc,
\n\
Monotonic clock, cannot go backward.");
-static PyObject*
-perf_counter(_Py_clock_info_t *info)
-{
- _PyTime_t t;
- if (_PyTime_GetPerfCounterWithInfo(&t, info) < 0) {
- return NULL;
- }
- return _PyFloat_FromPyTime(t);
-}
-
static PyObject *
time_perf_counter(PyObject *self, PyObject *unused)
{
diff --git a/Python/import.c b/Python/import.c
index d396b4d..76aa912 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1669,10 +1669,10 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
else {
static int ximporttime = 0;
static int import_level;
- static _PyTime_t accumulated;
+ static double accumulated;
_Py_IDENTIFIER(importtime);
- _PyTime_t t1 = 0, accumulated_copy = accumulated;
+ double t1 = 0, accumulated_copy = accumulated;
Py_XDECREF(mod);
@@ -1695,7 +1695,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
if (ximporttime) {
import_level++;
- t1 = _PyTime_GetPerfCounter();
+ t1 = _PyTime_GetPerfCounterDouble();
accumulated = 0;
}
@@ -1711,12 +1711,12 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
mod != NULL);
if (ximporttime) {
- _PyTime_t cum = _PyTime_GetPerfCounter() - t1;
+ double cum = _PyTime_GetPerfCounterDouble() - t1;
import_level--;
fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
- (long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING),
- (long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
+ (long)ceil((cum - accumulated) * 1e6),
+ (long)ceil(cum * 1e6),
import_level*2, "", PyUnicode_AsUTF8(abs_name));
accumulated = accumulated_copy + cum;
diff --git a/Python/pytime.c b/Python/pytime.c
index dbf1dda..7fd2a90 100644
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -801,8 +801,8 @@ _PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
#ifdef MS_WINDOWS
-int
-_PyTime_GetWinPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
+static int
+win_perf_counter(double *tp, _Py_clock_info_t *info)
{
static LONGLONG cpu_frequency = 0;
static LONGLONG ctrStart;
@@ -829,28 +829,33 @@ _PyTime_GetWinPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
}
diff = diff / (double)cpu_frequency;
- return _PyTime_FromDouble(t, diff, _PyTime_ROUND_FLOOR, SEC_TO_NS);
+ *tp = diff;
+ return 0;
}
#endif
int
-_PyTime_GetPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
+_PyTime_GetPerfCounterDoubleWithInfo(double *d, _Py_clock_info_t *info)
{
#ifdef MS_WINDOWS
- return _PyTime_GetWinPerfCounterWithInfo(t, info);
+ return win_perf_counter(d, info);
#else
- return _PyTime_GetMonotonicClockWithInfo(t, info);
+ _PyTime_t t;
+ if (_PyTime_GetMonotonicClockWithInfo(&t, info) < 0) {
+ return -1;
+ }
+ *d = _PyTime_AsSecondsDouble(t);
+ return 0;
#endif
}
-_PyTime_t
-_PyTime_GetPerfCounter(void)
+double
+_PyTime_GetPerfCounterDouble(void)
{
- _PyTime_t t;
- if (_PyTime_GetPerfCounterWithInfo(&t, NULL) < 0) {
- /* should not happen, _PyTime_Init() checked the clock at startup */
+ double t;
+ if (_PyTime_GetPerfCounterDoubleWithInfo(&t, NULL)) {
Py_UNREACHABLE();
}
return t;
@@ -860,17 +865,18 @@ _PyTime_GetPerfCounter(void)
int
_PyTime_Init(void)
{
- /* check that the 3 most important clocks are working properly
- to not have to check for exceptions at runtime. If a clock works once,
- it cannot fail in next calls. */
+ /* check that time.time(), time.monotonic() and time.perf_counter() clocks
+ are working properly to not have to check for exceptions at runtime. If
+ a clock works once, it cannot fail in next calls. */
_PyTime_t t;
+ double d;
if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0) {
return -1;
}
if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0) {
return -1;
}
- if (_PyTime_GetPerfCounterWithInfo(&t, NULL) < 0) {
+ if (_PyTime_GetPerfCounterDoubleWithInfo(&d, NULL) < 0) {
return -1;
}
return 0;