Search code examples
pythoncpu-usageclock

why same python code has different clock time?


I'm benchmarking my server using following python code:

import time
initial_clock = time.clock()
res = 0
for i in range(1, 10000000):
    res += i * i
print (time.clock() - initial_clock)

When I run it multiple times I get different execution times from 2.163377 seconds to 2.970836 seconds. I know same code may have different execution time due to variation in CPU load but as is said in time.clock documentation it only considers current process clocks, so it should have same execution time using time.clock() even if it is different using time.time(). shouldn't be?

Also is there anyway I can get exact clock count for a piece of python code?

EDIT: I use time.process_time() and get same result.


Solution

  • First rule of timing code: use the timeit module. This takes care of picking the best timer for your OS automatically, minimises other influences, and takes multiple timing runs to give you the most accurate estimate of time taken.

    Next, time.clock() is not process specific. It's the clock time on the CPU, yes, but not the amount of time the current process has spent using the CPU. Other processes scheduled to run on the CPU will add fluctuation to the time taken. You'd want to use time.process_time() instead.

    However, all code is subject to potential caching and to Python-specific periodic processes such as the garbage collector running. You can't expect to ever get repeatable time.clock() or time.process_time() values, because that clock can't account for such background work in the Python process itself. You can disable the garbage collector processes (timeit does this for you) while timing code but this won't help with internal caches (which are implementation specific and most are not documented).

    timeit uses time.perf_counter() to include time spent on I/O and other processes that might be kicked off by the code under test. You can tell it to use time.process_time() instead by using the -p switch when using timeit as a command line script, or passing timer=time.process_time when calling API functions.