This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: Rewrite _PyTime_GetWinPerfCounter() for _PyTime_t
Type: enhancement Stage: resolved
Components: Interpreter Core Versions: Python 3.7
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: vstinner
Priority: normal Keywords: patch

Created on 2017-10-12 14:14 by vstinner, last changed 2022-04-11 14:58 by admin. This issue is now closed.

File name Uploaded Description Edit vstinner, 2017-10-12 14:14
Pull Requests
URL Status Linked Edit
PR 3964 merged vstinner, 2017-10-12 14:37
PR 3983 merged vstinner, 2017-10-13 09:30
Messages (5)
msg304239 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-10-12 14:14
The commit a997c7b434631f51e00191acea2ba6097691e859 of bpo-31415 moved the implementation of time.perf_counter() from Modules/timemodule.c to Python/pytime.c. The change not only moved the code, but also changed the internal type storing time from floatting point number (C double) to integer number (_PyTyime_t = int64_t).

The drawback of this change is that time.perf_counter() now converts QueryPerformanceCounter() / QueryPerformanceFrequency() double into a _PyTime_t (integer) and then back to double. Two useless conversions required by the _PyTime_t format used in Python/pytime.c. These conversions introduced a loss of precision.

Try attached script which implements the double <=> _PyTime_t conversions and checks to check for precision loss. The script shows that we loose precision even with a single second for QueryPerformanceFrequency() == 3579545.

It seems like QueryPerformanceFrequency() now returns 10 ** 7 (10_000_000, resolution of 100 ns) on Windows 8 and newer, but returns 3,579,545 (3.6 MHz, resolution of 279 ns) on Windows 7. It depends maybe on the hardware clock, I don't know. Anyway, whenever possible, we should avoid precision loss of a clock.
msg304263 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-10-12 15:51
New changeset cba9a0c6def70549046f1afa6a80e38fe706520e by Victor Stinner in branch 'master':
bpo-31773: time.perf_counter() uses again double (GH-3964)
msg304327 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-10-13 09:52
I reopen the issue since I found a solution to only use integer in pytime.c for QueryPerformanceCounter() / QueryPerformanceFrequency() *and* prevent integer overflow.
msg304477 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-10-16 15:44
New changeset bdaeb7d237462a629e6c85001317faa85f94a0c6 by Victor Stinner in branch 'master':
bpo-31773: _PyTime_GetPerfCounter() uses _PyTime_t (GH-3983)
msg304877 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-10-24 09:06
Buildbots seem to be happy, I close the issue.

See my new PEP 564 for the next chapiter of this story ;-)
Date User Action Args
2022-04-11 14:58:53adminsetgithub: 75954
2017-10-24 09:06:08vstinnersetstatus: open -> closed
resolution: fixed
messages: + msg304877
2017-10-16 15:44:38vstinnersetmessages: + msg304477
2017-10-13 09:52:23vstinnersetstatus: closed -> open
resolution: fixed -> (no value)
messages: + msg304327
2017-10-13 09:30:02vstinnersetpull_requests: + pull_request3959
2017-10-12 15:52:16vstinnersetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2017-10-12 15:51:58vstinnersetmessages: + msg304263
2017-10-12 14:37:59vstinnersetkeywords: + patch
stage: patch review
pull_requests: + pull_request3943
2017-10-12 14:14:14vstinnercreate