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.
This commit is contained in:
parent
0e61e67a57
commit
cba9a0c6de
|
@ -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. */
|
Return 0 on success, raise an exception and return -1 on error. */
|
||||||
PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
|
PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
/* Get the performance counter: clock with the highest available resolution to
|
||||||
PyAPI_FUNC(int) _PyTime_GetWinPerfCounterWithInfo(
|
measure a short duration.
|
||||||
_PyTime_t *t,
|
|
||||||
_Py_clock_info_t *info);
|
The function cannot fail. _PyTime_Init() ensures that the system clock
|
||||||
#endif
|
works. */
|
||||||
|
PyAPI_FUNC(double) _PyTime_GetPerfCounterDouble(void);
|
||||||
|
|
||||||
/* Get the performance counter: clock with the highest available resolution to
|
/* Get the performance counter: clock with the highest available resolution to
|
||||||
measure a short duration. */
|
measure a short duration.
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void);
|
|
||||||
|
|
||||||
/* Similar to _PyTime_GetPerfCounter(),
|
Fill info (if set) with information of the function used to get the time.
|
||||||
but get also clock info if info is non-NULL. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo(
|
Return 0 on success, raise an exception and return -1 on error. */
|
||||||
_PyTime_t *t,
|
PyAPI_FUNC(int) _PyTime_GetPerfCounterDoubleWithInfo(
|
||||||
|
double *t,
|
||||||
_Py_clock_info_t *info);
|
_Py_clock_info_t *info);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -88,19 +88,23 @@ floatclock(_Py_clock_info_t *info)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_CLOCK */
|
#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)
|
#if defined(MS_WINDOWS) || defined(HAVE_CLOCK)
|
||||||
#define PYCLOCK
|
#define PYCLOCK
|
||||||
static PyObject*
|
static PyObject*
|
||||||
pyclock(_Py_clock_info_t *info)
|
pyclock(_Py_clock_info_t *info)
|
||||||
{
|
{
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
/* Win32 has better clock replacement; we have our own version, due to Mark
|
return perf_counter(info);
|
||||||
Hammond and Tim Peters */
|
|
||||||
_PyTime_t t;
|
|
||||||
if (_PyTime_GetWinPerfCounterWithInfo(&t, info) < 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return _PyFloat_FromPyTime(t);
|
|
||||||
#else
|
#else
|
||||||
return floatclock(info);
|
return floatclock(info);
|
||||||
#endif
|
#endif
|
||||||
|
@ -936,16 +940,6 @@ PyDoc_STRVAR(monotonic_doc,
|
||||||
\n\
|
\n\
|
||||||
Monotonic clock, cannot go backward.");
|
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 *
|
static PyObject *
|
||||||
time_perf_counter(PyObject *self, PyObject *unused)
|
time_perf_counter(PyObject *self, PyObject *unused)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1669,10 +1669,10 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
else {
|
else {
|
||||||
static int ximporttime = 0;
|
static int ximporttime = 0;
|
||||||
static int import_level;
|
static int import_level;
|
||||||
static _PyTime_t accumulated;
|
static double accumulated;
|
||||||
_Py_IDENTIFIER(importtime);
|
_Py_IDENTIFIER(importtime);
|
||||||
|
|
||||||
_PyTime_t t1 = 0, accumulated_copy = accumulated;
|
double t1 = 0, accumulated_copy = accumulated;
|
||||||
|
|
||||||
Py_XDECREF(mod);
|
Py_XDECREF(mod);
|
||||||
|
|
||||||
|
@ -1695,7 +1695,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
|
|
||||||
if (ximporttime) {
|
if (ximporttime) {
|
||||||
import_level++;
|
import_level++;
|
||||||
t1 = _PyTime_GetPerfCounter();
|
t1 = _PyTime_GetPerfCounterDouble();
|
||||||
accumulated = 0;
|
accumulated = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1711,12 +1711,12 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
mod != NULL);
|
mod != NULL);
|
||||||
|
|
||||||
if (ximporttime) {
|
if (ximporttime) {
|
||||||
_PyTime_t cum = _PyTime_GetPerfCounter() - t1;
|
double cum = _PyTime_GetPerfCounterDouble() - t1;
|
||||||
|
|
||||||
import_level--;
|
import_level--;
|
||||||
fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
|
fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
|
||||||
(long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING),
|
(long)ceil((cum - accumulated) * 1e6),
|
||||||
(long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
|
(long)ceil(cum * 1e6),
|
||||||
import_level*2, "", PyUnicode_AsUTF8(abs_name));
|
import_level*2, "", PyUnicode_AsUTF8(abs_name));
|
||||||
|
|
||||||
accumulated = accumulated_copy + cum;
|
accumulated = accumulated_copy + cum;
|
||||||
|
|
|
@ -801,8 +801,8 @@ _PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
|
||||||
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
int
|
static int
|
||||||
_PyTime_GetWinPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
|
win_perf_counter(double *tp, _Py_clock_info_t *info)
|
||||||
{
|
{
|
||||||
static LONGLONG cpu_frequency = 0;
|
static LONGLONG cpu_frequency = 0;
|
||||||
static LONGLONG ctrStart;
|
static LONGLONG ctrStart;
|
||||||
|
@ -829,28 +829,33 @@ _PyTime_GetWinPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
diff = diff / (double)cpu_frequency;
|
diff = diff / (double)cpu_frequency;
|
||||||
return _PyTime_FromDouble(t, diff, _PyTime_ROUND_FLOOR, SEC_TO_NS);
|
*tp = diff;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_PyTime_GetPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
|
_PyTime_GetPerfCounterDoubleWithInfo(double *d, _Py_clock_info_t *info)
|
||||||
{
|
{
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
return _PyTime_GetWinPerfCounterWithInfo(t, info);
|
return win_perf_counter(d, info);
|
||||||
#else
|
#else
|
||||||
return _PyTime_GetMonotonicClockWithInfo(t, info);
|
_PyTime_t t;
|
||||||
|
if (_PyTime_GetMonotonicClockWithInfo(&t, info) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*d = _PyTime_AsSecondsDouble(t);
|
||||||
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_PyTime_t
|
double
|
||||||
_PyTime_GetPerfCounter(void)
|
_PyTime_GetPerfCounterDouble(void)
|
||||||
{
|
{
|
||||||
_PyTime_t t;
|
double t;
|
||||||
if (_PyTime_GetPerfCounterWithInfo(&t, NULL) < 0) {
|
if (_PyTime_GetPerfCounterDoubleWithInfo(&t, NULL)) {
|
||||||
/* should not happen, _PyTime_Init() checked the clock at startup */
|
|
||||||
Py_UNREACHABLE();
|
Py_UNREACHABLE();
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
|
@ -860,17 +865,18 @@ _PyTime_GetPerfCounter(void)
|
||||||
int
|
int
|
||||||
_PyTime_Init(void)
|
_PyTime_Init(void)
|
||||||
{
|
{
|
||||||
/* check that the 3 most important clocks are working properly
|
/* check that time.time(), time.monotonic() and time.perf_counter() clocks
|
||||||
to not have to check for exceptions at runtime. If a clock works once,
|
are working properly to not have to check for exceptions at runtime. If
|
||||||
it cannot fail in next calls. */
|
a clock works once, it cannot fail in next calls. */
|
||||||
_PyTime_t t;
|
_PyTime_t t;
|
||||||
|
double d;
|
||||||
if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0) {
|
if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0) {
|
if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (_PyTime_GetPerfCounterWithInfo(&t, NULL) < 0) {
|
if (_PyTime_GetPerfCounterDoubleWithInfo(&d, NULL) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue