-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
gh-88494: Use QueryPerformanceCounter() for time.monotonic() #116781
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
Conversation
On Windows, time.monotonic() now uses the QueryPerformanceCounter() clock to have a resolution better than 1 us, instead of the gGetTickCount64() clock which has a resolution of 15.6 ms.
Script to measure the effective clock resolution: import time
def compute_resolution(func):
resolution = None
points = 0
timeout = time.monotonic() + 1.0
previous = func()
while time.monotonic() < timeout or points < 3:
for loop in range(10):
t1 = func()
t2 = func()
dt = t2 - t1
if 0 < dt:
break
else:
dt = t2 - previous
if dt <= 0.0:
continue
if resolution is not None:
resolution = min(resolution, dt)
else:
resolution = dt
points += 1
previous = func()
return resolution
def format_duration(dt):
if dt >= 1e-3:
return "%.0f ms" % (dt * 1e3)
if dt >= 1e-6:
return "%.0f us" % (dt * 1e6)
else:
return "%.0f ns" % (dt * 1e9)
def test_clock(name, func):
print("%s:" % name)
resolution = compute_resolution(func)
print("- efffective resolution: %s" % format_duration(resolution))
clocks = ['time', 'perf_counter', 'monotonic']
for name in clocks:
func = getattr(time, name)
test_clock("%s()" % name, func)
info = time.get_clock_info(name)
print("- implementation: %s" % info.implementation)
print("- resolution: %s" % format_duration(info.resolution))
print() Results before (release build):
Results after (release build):
monotonic() resolution changes from 15.6 ms to 100 ns: it's 156,000x more accurate than before! |
…ython#116781) On Windows, time.monotonic() now uses the QueryPerformanceCounter() clock to have a resolution better than 1 us, instead of the gGetTickCount64() clock which has a resolution of 15.6 ms.
…ython#116781) On Windows, time.monotonic() now uses the QueryPerformanceCounter() clock to have a resolution better than 1 us, instead of the gGetTickCount64() clock which has a resolution of 15.6 ms.
…ython#116781) On Windows, time.monotonic() now uses the QueryPerformanceCounter() clock to have a resolution better than 1 us, instead of the gGetTickCount64() clock which has a resolution of 15.6 ms.
Closes dask#8641. _WindowsTime is no longer needed on Windows with Python 3.13. On Windows, Python 3.13 now uses GetSystemTimePreciseAsFileTime() for time.time() and QueryPerformanceCounter() for time.monotonic(). * python/cpython#116781 * python/cpython#116822
Closes #8641. _WindowsTime is no longer needed on Windows with Python 3.13. On Windows, Python 3.13 now uses GetSystemTimePreciseAsFileTime() for time.time() and QueryPerformanceCounter() for time.monotonic(). * python/cpython#116781 * python/cpython#116822
@vstinner could you, please, help me figure out why the script works this way? Specifically, by taking 10 clock readings to measure |
With precise clocks such as QueryPerformanceCounter(), you don't go into the "else" block of the "for". The "else" is only there for low-resolution clocks. |
Got it, thanks |
On Windows, time.monotonic() now uses the QueryPerformanceCounter() clock to have a resolution better than 1 us, instead of the gGetTickCount64() clock which has a resolution of 15.6 ms.
📚 Documentation preview 📚: https://cpython-previews--116781.org.readthedocs.build/