Skip to content

Commit 4ef53f4

Browse files
committed
gh-88494: Use GetSystemTimePreciseAsFileTime() in time.time()
1 parent b54d7c8 commit 4ef53f4

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

Doc/whatsnew/3.13.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,12 @@ time
560560
instead of the ``GetTickCount64()`` clock which has a resolution of 15.6 ms.
561561
(Contributed by Victor Stinner in :gh:`88494`.)
562562

563+
* On Windows, :func:`time.time()` now uses the
564+
``GetSystemTimePreciseAsFileTime()`` clock to have a resolution better
565+
than 1 us, instead of the ``GetSystemTimeAsFileTime()`` clock which has a
566+
resolution of 15.6 ms.
567+
(Contributed by Victor Stinner in :gh:`88494`.)
568+
563569

564570
tkinter
565571
-------
Lines changed: 4 additions & 0 deletions
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

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
895895
FILETIME system_time;
896896
ULARGE_INTEGER large;
897897

898-
GetSystemTimeAsFileTime(&system_time);
898+
GetSystemTimePreciseAsFileTime(&system_time);
899899
large.u.LowPart = system_time.dwLowDateTime;
900900
large.u.HighPart = system_time.dwHighDateTime;
901901
/* 11,644,473,600,000,000,000: number of nanoseconds between
@@ -904,18 +904,17 @@ py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
904904
PyTime_t ns = large.QuadPart * 100 - 11644473600000000000;
905905
*tp = ns;
906906
if (info) {
907-
DWORD timeAdjustment, timeIncrement;
908-
BOOL isTimeAdjustmentDisabled, ok;
907+
// GetSystemTimePreciseAsFileTime() is implemented using
908+
// QueryPerformanceCounter() internally.
909+
if (py_qpc_base.denom == 0) {
910+
if (py_win_perf_counter_frequency(&py_qpc_base, raise_exc) < 0) {
911+
return -1;
912+
}
913+
}
909914

910-
info->implementation = "GetSystemTimeAsFileTime()";
915+
info->implementation = "GetSystemTimePreciseAsFileTime()";
911916
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;
917+
info->resolution = _PyTimeFraction_Resolution(&py_qpc_base);
919918
info->adjustable = 1;
920919
}
921920

@@ -1057,22 +1056,23 @@ py_win_perf_counter_frequency(_PyTimeFraction *base, int raise_exc)
10571056
}
10581057

10591058

1059+
static _PyTimeFraction py_qpc_base = {0, 0};
1060+
10601061
// N.B. If raise_exc=0, this may be called without the GIL.
10611062
static int
10621063
py_get_win_perf_counter(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
10631064
{
10641065
assert(info == NULL || raise_exc);
10651066

1066-
static _PyTimeFraction base = {0, 0};
1067-
if (base.denom == 0) {
1068-
if (py_win_perf_counter_frequency(&base, raise_exc) < 0) {
1067+
if (py_qpc_base.denom == 0) {
1068+
if (py_win_perf_counter_frequency(&py_qpc_base, raise_exc) < 0) {
10691069
return -1;
10701070
}
10711071
}
10721072

10731073
if (info) {
10741074
info->implementation = "QueryPerformanceCounter()";
1075-
info->resolution = _PyTimeFraction_Resolution(&base);
1075+
info->resolution = _PyTimeFraction_Resolution(&py_qpc_base);
10761076
info->monotonic = 1;
10771077
info->adjustable = 0;
10781078
}

0 commit comments

Comments
 (0)