Skip to content

Commit 1d95451

Browse files
authored
gh-63207: Use GetSystemTimePreciseAsFileTime() in time.time() (#116822)
1 parent c80d2d3 commit 1d95451

File tree

3 files changed

+32
-16
lines changed

3 files changed

+32
-16
lines changed

Doc/whatsnew/3.13.rst

+6
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,12 @@ time
570570
instead of the ``GetTickCount64()`` clock which has a resolution of 15.6 ms.
571571
(Contributed by Victor Stinner in :gh:`88494`.)
572572

573+
* On Windows, :func:`time.time()` now uses the
574+
``GetSystemTimePreciseAsFileTime()`` clock to have a resolution better
575+
than 1 us, instead of the ``GetSystemTimeAsFileTime()`` clock which has a
576+
resolution of 15.6 ms.
577+
(Contributed by Victor Stinner in :gh:`63207`.)
578+
573579

574580
tkinter
575581
-------
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
On Windows, :func:`time.time()` now uses the
2+
``GetSystemTimePreciseAsFileTime()`` clock to have a resolution better than 1
3+
us, instead of the ``GetSystemTimeAsFileTime()`` clock which has a resolution
4+
of 15.6 ms. Patch by Victor Stinner.

Python/pytime.c

+22-16
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@
5555
#endif
5656

5757

58+
#ifdef MS_WINDOWS
59+
static _PyTimeFraction py_qpc_base = {0, 0};
60+
61+
// Forward declaration
62+
static int py_win_perf_counter_frequency(_PyTimeFraction *base, int raise_exc);
63+
#endif
64+
65+
5866
static PyTime_t
5967
_PyTime_GCD(PyTime_t x, PyTime_t y)
6068
{
@@ -895,7 +903,7 @@ py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
895903
FILETIME system_time;
896904
ULARGE_INTEGER large;
897905

898-
GetSystemTimeAsFileTime(&system_time);
906+
GetSystemTimePreciseAsFileTime(&system_time);
899907
large.u.LowPart = system_time.dwLowDateTime;
900908
large.u.HighPart = system_time.dwHighDateTime;
901909
/* 11,644,473,600,000,000,000: number of nanoseconds between
@@ -904,18 +912,17 @@ py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
904912
PyTime_t ns = large.QuadPart * 100 - 11644473600000000000;
905913
*tp = ns;
906914
if (info) {
907-
DWORD timeAdjustment, timeIncrement;
908-
BOOL isTimeAdjustmentDisabled, ok;
915+
// GetSystemTimePreciseAsFileTime() is implemented using
916+
// QueryPerformanceCounter() internally.
917+
if (py_qpc_base.denom == 0) {
918+
if (py_win_perf_counter_frequency(&py_qpc_base, raise_exc) < 0) {
919+
return -1;
920+
}
921+
}
909922

910-
info->implementation = "GetSystemTimeAsFileTime()";
923+
info->implementation = "GetSystemTimePreciseAsFileTime()";
911924
info->monotonic = 0;
912-
ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
913-
&isTimeAdjustmentDisabled);
914-
if (!ok) {
915-
PyErr_SetFromWindowsErr(0);
916-
return -1;
917-
}
918-
info->resolution = timeIncrement * 1e-7;
925+
info->resolution = _PyTimeFraction_Resolution(&py_qpc_base);
919926
info->adjustable = 1;
920927
}
921928

@@ -1063,16 +1070,15 @@ py_get_win_perf_counter(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
10631070
{
10641071
assert(info == NULL || raise_exc);
10651072

1066-
static _PyTimeFraction base = {0, 0};
1067-
if (base.denom == 0) {
1068-
if (py_win_perf_counter_frequency(&base, raise_exc) < 0) {
1073+
if (py_qpc_base.denom == 0) {
1074+
if (py_win_perf_counter_frequency(&py_qpc_base, raise_exc) < 0) {
10691075
return -1;
10701076
}
10711077
}
10721078

10731079
if (info) {
10741080
info->implementation = "QueryPerformanceCounter()";
1075-
info->resolution = _PyTimeFraction_Resolution(&base);
1081+
info->resolution = _PyTimeFraction_Resolution(&py_qpc_base);
10761082
info->monotonic = 1;
10771083
info->adjustable = 0;
10781084
}
@@ -1088,7 +1094,7 @@ py_get_win_perf_counter(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
10881094
"LONGLONG is larger than PyTime_t");
10891095
ticks = (PyTime_t)ticksll;
10901096

1091-
*tp = _PyTimeFraction_Mul(ticks, &base);
1097+
*tp = _PyTimeFraction_Mul(ticks, &py_qpc_base);
10921098
return 0;
10931099
}
10941100
#endif // MS_WINDOWS

0 commit comments

Comments
 (0)