Search code examples
pythonwindowstimeclockperformancecounter

Python 2.x - QueryPerformanceCounter() on Windows


I would like to program my own clock object using Python. I'd like it to be very, very accurate. I read that on Windows, I could use QueryPerformanceCounter(). But how? I don't know any C; only Python 2.x.

Can someone give me a hint on how to make use of this in Python to make an accurate clock on Win?


Solution

  • I've ported the C++ example you've given to Python using the ctypes module:

    C++

    LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
    LARGE_INTEGER Frequency;
    
    QueryPerformanceFrequency(&Frequency); 
    QueryPerformanceCounter(&StartingTime);
    
    // Activity to be timed
    
    QueryPerformanceCounter(&EndingTime);
    ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
    
    ElapsedMicroseconds.QuadPart *= 1000000;
    ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
    

    Python

    import ctypes
    import ctypes.wintypes
    import time
    
    kernel32             = ctypes.WinDLL('kernel32', use_last_error=True)
    
    starting_time        = ctypes.wintypes.LARGE_INTEGER()
    ending_time          = ctypes.wintypes.LARGE_INTEGER()
    elapsed_microseconds = ctypes.wintypes.LARGE_INTEGER()
    frequency            = ctypes.wintypes.LARGE_INTEGER()
    
    kernel32.QueryPerformanceFrequency(ctypes.byref(frequency)) 
    kernel32.QueryPerformanceCounter(ctypes.byref(starting_time))
    
    # Activity to be timed, e.g.
    time.sleep(2)
    
    kernel32.QueryPerformanceCounter(ctypes.byref(ending_time))
    
    elapsed_microseconds = ending_time.value - starting_time.value
    elapsed_microseconds *= 1000000
    elapsed_microseconds /= frequency.value
    
    print(elapsed_microseconds)
    

    I really appreciate the useful hints of @eryksun!

    The code above should print something near to 2000000 (e.g. 2000248.7442040185, the value may be different from time to time). You may also use the round() or int() function to get rid of the decimals.

    As @eryksun has commented you can also use time.clock(), which is implemented in C and also uses QueryPerformanceCounter().

    Example doing exactly the same as the one using ctypes:

    import time
    starting_time = time.clock()
    
    # Activity to be timed, e.g.
    time.sleep(2)
    
    ending_time = time.clock()
    
    elapsed_microseconds = ending_time - starting_time
    elapsed_microseconds *= 1000000
    
    print(elapsed_microseconds)
    

    Hope this helps!