Skip to content

time.process_time() constant / erratic on Windows #82040

Closed

Description

@RedGlyph
mannequin
BPO 37859
Nosy @pfmoore, @vstinner, @tjguk, @zware, @eryksun, @zooba

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2019-08-14.20:48:14.849>
created_at = <Date 2019-08-14.20:32:41.783>
labels = ['type-bug', '3.8', 'invalid', '3.7', 'library', 'OS-windows']
title = 'time.process_time() constant / erratic on Windows'
updated_at = <Date 2019-08-14.21:54:45.041>
user = 'https://bugs.python.org/RedGlyph'

bugs.python.org fields:

activity = <Date 2019-08-14.21:54:45.041>
actor = 'vstinner'
assignee = 'none'
closed = True
closed_date = <Date 2019-08-14.20:48:14.849>
closer = 'zach.ware'
components = ['Library (Lib)', 'Windows']
creation = <Date 2019-08-14.20:32:41.783>
creator = 'Red Glyph'
dependencies = []
files = []
hgrepos = []
issue_num = 37859
keywords = []
message_count = 6.0
messages = ['349745', '349746', '349748', '349759', '349762', '349763']
nosy_count = 7.0
nosy_names = ['paul.moore', 'vstinner', 'tim.golden', 'zach.ware', 'eryksun', 'steve.dower', 'Red Glyph']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue37859'
versions = ['Python 3.7', 'Python 3.8']

Activity

  1. RedGlyph commented on Aug 14, 2019

    RedGlyphmannequin
    MannequinAuthor

    Tested with

    • Python 3.7.4, 64-bit, Windows version (installer version)
    • python-3.8.0b3-embed-amd64.zip
    • python-3.7.2.post1-embed-amd64.zip
      on Windows 7 x64 Professional

    time.process_time() always returns the same value. If I check the value of time.process_time_ns(), sometimes it is constant, sometimes I observe a few changes, then it becomes constant too.

    Here is a log of an example session, I'm waiting at least 1-2 seconds between each command:

    Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license()" for more information.
    >>> import time
    >>> time.process_time()
    0.1092007
    >>> time.process_time()
    0.1092007
    >>> time.process_time_ns()
    109200700
    >>> time.process_time_ns()
    124800800
    >>> time.process_time_ns()
    124800800
    >>> time.process_time()
    0.1248008
    >>> time.process_time()
    0.1248008
    >>> time.process_time()
    0.1248008
    >>> time.process_time_ns()
    124800800
    >>> time.process_time_ns()
    124800800
    >>> time.process_time_ns()
    124800800
    >>> time.process_time_ns()
    124800800
    >>> time.clock()
    
    Warning (from warnings module):
      File "__main__", line 1
    DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead
    77.006126126
    >>> time.clock()
    79.245575778
    >>> time.clock()
    80.801103036
    >>> time.process_time()
    0.1248008
    >>>
  2. added
    stdlibStandard Library Python modules in the Lib/ directory
    type-bugAn unexpected behavior, bug, or error
    on Aug 14, 2019
  3. zware commented on Aug 14, 2019

    @zware
    Member

    Try this:

    while time.process_time() < 0.5:
        print('.', flush=True, end='')

    Or:

    >>> time.process_time()
    0.03125
    >>> len(str(2**500_000))
    150515
    >>> time.process_time()
    0.484375

    Basically, process_time() (and process_time_ns()) measure CPU time used by the process, and you aren't making the CPU do anything between your checks.

  4. reopened this on Aug 14, 2019
  5. RedGlyph commented on Aug 14, 2019

    RedGlyphmannequin
    MannequinAuthor

    I see that now. The behaviour was different in Linux, though, I suppose it may benefit from a more precise counter, but since in Windows it also has a precise counter with time.perf_counter_ns(), I was expecting to see that value change, but it was mainly a confusion with the older time.clock().

    Thanks!

  6. eryksun commented on Aug 14, 2019

    @eryksun
    Contributor

    I suppose it may benefit from a more precise counter, but since in
    Windows it also has a precise counter with time.perf_counter_ns(),
    I was expecting to see that value change, but it was mainly a
    confusion with the older time.clock().

    Don't read too much into the clock info here:

        >>> time.get_clock_info('process_time').resolution
        1e-07

    Process times [1] are stored as a 64-bit integer in units of 100 ns (1e-7). But the kernel schedules threads based on a timer that ticks every 15.625 ms by default. It can be lowered to about 0.5 ms, but this degrades battery life.

    [1] https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes

  7. vstinner commented on Aug 14, 2019

    @vstinner
    Member

    Process times [1] are stored as a 64-bit integer in units of 100 ns (1e-7). But the kernel schedules threads based on a timer that ticks every 15.625 ms by default. It can be lowered to about 0.5 ms, but this degrades battery life.

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

    Don't rely too much on time.get_clock_info() on Linux neither: it basically always say 1 ns, even if the effective resolution is way worse.

    See the PEP-418 for some numbers:
    https://www.python.org/dev/peps/pep-0418/#process-time

    I wrote these programs to write this PEP ;-)

    https://github.com/python/peps/tree/master/pep-0418

  8. vstinner commented on Aug 14, 2019

    @vstinner
    Member

    I see that now. The behaviour was different in Linux, though, I suppose it may benefit from a more precise counter, but since in Windows it also has a precise counter with time.perf_counter_ns(), I was expecting to see that value change, but it was mainly a confusion with the older time.clock().

    On Windows, time.clock() was implemented with QueryPerformanceCounter(). This function became time.perf_counter() in Python 3.4. time.clock() was removed. Use time.get_clock_info('perf_counter') ;-)

    The PEP-418 introduces new well defined clocks, since time.clock() was not portable.

    perf_counter and process_time have very different properties. process_time is stopped when the process sleeps, for example.

    https://docs.python.org/dev/library/time.html#time.perf_counter
    https://docs.python.org/dev/library/time.html#time.process_time

  9. transferred this issue fromon Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.7 (EOL)end of life3.8 (EOL)end of lifeOS-windowsstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions