gh-88494: Use QueryPerformanceCounter() for time.monotonic()#116781
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.
Sorry, something went wrong.
|
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! |
Sorry, something went wrong.
…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 |
Sorry, something went wrong.
|
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. |
Sorry, something went wrong.
|
Got it, thanks |
Sorry, something went wrong.
On Windows, time.monotonic() now uses the QueryPerformanceCounter() clock to have a resolution better than 1 us, instead of the GetTickCount64() clock which has a resolution of 15.6 ms.
📚 Documentation preview 📚: https://cpython-previews--116781.org.readthedocs.build/