Skip to content

GH-135304: Reported resolution of time.process_time and time.thread_time is wrong on Windows #135305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

chris-eibl
Copy link
Member

@chris-eibl chris-eibl commented Jun 9, 2025

>>> import time
>>> time.get_clock_info("process_time")
namespace(implementation='GetProcessTimes()', monotonic=True, adjustable=False, resolution=1e-07)
>>> time.get_clock_info("thread_time")
namespace(implementation='GetThreadTimes()', monotonic=True, adjustable=False, resolution=1e-07)

I suggest to report 15.625 ms, since this is the upper limit.

@chris-eibl
Copy link
Member Author

The existing tests

self.assertIsInstance(info.resolution, float)
# 0.0 < resolution <= 1.0
self.assertGreater(info.resolution, 0.0)
self.assertLessEqual(info.resolution, 1.0)

still pass and are IMHO sufficient: no need to hardcode platform specific values here.

I've manually verified the new values:

>>> time.get_clock_info("process_time")
namespace(implementation='GetProcessTimes()', monotonic=True, adjustable=False, resolution=0.015625)
>>> time.get_clock_info("thread_time")
namespace(implementation='GetThreadTimes()', monotonic=True, adjustable=False, resolution=0.015625)

@chris-eibl
Copy link
Member Author

cc @vstinner since #82040 (comment)

Patches are welcome to enhance time.get_clock_info() :-)

@chris-eibl chris-eibl requested a review from vstinner June 9, 2025 15:44
@chris-eibl chris-eibl changed the title GH-135304: Reported resolution of time.process_time and time.thread_time is wrong on Windows GH-135304: Reported resolution of time.process_time and time.thread_time is wrong on Windows Jun 9, 2025
@zooba
Copy link
Member

zooba commented Jun 9, 2025

This isn't the way, I'm afraid. The specified resolution is all we know, and undocumented behaviours like the resolution a system is actually going to write into the data structures isn't something we should be hard coding and relying on.

These functions should really only be used for reporting, not for decision making. If tests want to use them for decision making, then they also need a control to verify that they're going to work as intended (e.g. run a known amount of work and make sure that it registers in these functions).

At worst, we should try and read the current interval, rather than hard-coding the worst case scenario. But even that's risky, as it can change while the system is running (not a great idea, because programs do rely on it, and they can get into trouble as it changes, but we shouldn't be encouraging people to write code like tht).

@chris-eibl
Copy link
Member Author

chris-eibl commented Jun 9, 2025

Ah, ok, I see. Even the PEP (https://peps.python.org/pep-0418/#process-time) lists

Name Operating system OS Resolution Python Resolution
GetProcessTimes() Windows Seven 16 ms 16 ms

These functions should really only be used for reporting, not for decision making

Seems to happen even in the stdlib

# Ensuring that we chose a slow enough conversion to measure.
# It takes 0.1 seconds on a Zen based cloud VM in an opt build.
# Some OSes have a low res 1/64s timer, skip if hard to measure.
if sw_convert.seconds < sw_convert.clock_info.resolution * 2:

That's where I came from :)

Maybe just a documentation issue?

Converting to draft tagging as DO-NOT-MERGE ...

@zooba
Copy link
Member

zooba commented Jun 9, 2025

The PEP isn't the documentation of the OS. If you can find a reference on learn.microsoft.com that states the resolution of that specific function, then we can lock it in. But you won't, because the resolution of the actual timer is deliberately left unspecified. (You'll find examples showing that it's typically around 15ms and adjustable down for some benefit in some situations, but no guarantees.)

A lot of code in the stdlib, and especially its test suite, is "best effort" to make something work. It's not necessarily a robust example of the best way to implement something. Trust the upstream docs, just like we expect people to trust ours 😉

@chris-eibl
Copy link
Member Author

Oh yes, I frequently read the MSDN :)

With

Maybe just a documentation issue?

I meant we could add some hints about that to https://docs.python.org/3/library/time.html#time.get_clock_info

resolution: The resolution of the clock in seconds (float)

Specifically something like

These functions should really only be used for reporting, not for decision making

@zooba
Copy link
Member

zooba commented Jun 9, 2025

Clarifying documentation is always fine, provided it doesn't specify us into a corner. Something along the lines of "this is a theoretical resolution, and not necessarily the rate at which the values are updated" and "these functions should not be treated as high-precision timers on most operating systems" would be fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants