Python's Time.Clock() VS. Time.Time() Accuracy

what is the difference between time.time and time.clock?

time.clock() gives you an elapsed amount of time. time.time() gives you the wall clock time.

You can use time.time() to communicate with others (including humans) about when something happened. time.clock() only lets you measure how long something takes.

Generally speaking, you'd use time.clock() when you want to measure timings, time.time() to schedule something. To that end time.time() has to be set correctly on your computer (to agree with the rest of your region as to what time it is now), but time.clock() doesn't, it just counts seconds from an arbitrary point in time (usually when your computer started or when your process first used the function).

The exact behaviour of time.clock() depends on your OS (it could just measure process time, excluding time sleeping, or it could measure time elapsed even when the process is inactive, it could go backwards if your system time is adjusted, etc).

For some use-cases this variability in exact behaviour isn't good enough, and as such it is deprecated in Python 3. There better options are available for either measuring performance or process time, see time.perf_counter() and time.process_time().

High-precision clock in Python

The standard time.time() function provides sub-second precision, though that precision varies by platform. For Linux and Mac precision is +- 1 microsecond or 0.001 milliseconds. Python on Windows uses +- 16 milliseconds precision due to clock implementation problems due to process interrupts. The timeit module can provide higher resolution if you're measuring execution time.

>>> import time
>>> time.time() #return seconds from epoch
1261367718.971009

Python 3.7 introduces new functions to the time module that provide higher resolution:

>>> import time
>>> time.time_ns()
1530228533161016309
>>> time.time_ns() / (10 ** 9) # convert to floating-point seconds
1530228544.0792289

Understanding time.clock() and time.time()

In a multi-processing system (such as Linux or Windows), several independent processes each run in turn. While one process is running, all of the other processes are waiting*. Occasionally the running process gives up its turn (sometimes cooperatively, sometimes it is forced to stop running). Some other process then gets a turn to run.

This process switch can happen dozens, hundreds or even thousands of times per second. From the human user's perspective, all of the processes appear to be running simultaneously. But in truth, they are all running in turns.

When a process invokes time.sleep(2.5), it announces that it is giving up the remainder of its current turn, and is not interested in any future turns for at least the next 2.5 seconds. So, for the next 2.5 seconds, it consumes no processor time.

Conversely, if this were the only process in the system:

while True:
i += 1

it would never give up its turn; it would use 100% of the processor.

So, what has this to do with time.clock()? In Linux, time.clock() returns the sum of the durations of all of the turns that your process has taken since it was first launched. This is a fair measure of how hard your process's task is. If you only measure wall-clock time (i.e. time.time()), then your task's duration would depend upon how many other processes were running and what they were doing.


* This description is valid for single processor multiprocessing systems. For multiprocessor sytems (or multi-core systems), a number of processes actually can run simultaneously. Regardless, time.clock() returns the sum of the durations all of the turns taken.

Why is time.clock giving a greater elapsed time than time.time?

CPU time can exceed wall time if you execute on multiple CPUs. I've not specifically seen this in Python, but I've definitely seen this when using the clock function with multiple threads from C, and presumably the Python code is just directly calling this C function.

Regarding "why": you're thinking about it the wrong way. What's important is how many cores are running your program. If one core runs for one second over the course of two seconds of wall time that makes sense to you, but what if four cores each run for one second over that same time interval. Then you have 4 seconds of CPU time in 2 seconds of wall time. The kernel accounts for CPU time measuring all cores. If multiple cores run during the same second then you spent multiple CPU seconds during that second. That's the cost measurement that matters to the scheduler, and presumably that's the metric which clock is built upon. This may not be the metric you care about, but that's how it works.

What does python time.clock() return?

From https://docs.python.org/2.7/library/time.html,

time.clock()

On Unix, return the current processor time as a floating point number expressed in seconds. The precision, and in fact
the very definition of the meaning of “processor time”, depends on
that of the C function of the same name, but in any case, this is the
function to use for benchmarking Python or timing algorithms.

On Windows, this function returns wall-clock seconds elapsed since the
first call to this function, as a floating point number, based on the
Win32 function QueryPerformanceCounter(). The resolution is typically
better than one microsecond.

As you can see, it is platform-dependent. A better solution is to use datetime.now()

from datetime import datetime

t0 = datetime.now()
# ... do something ...
elapsed = datetime.now() - t0

High-precision clock in Python

The standard time.time() function provides sub-second precision, though that precision varies by platform. For Linux and Mac precision is +- 1 microsecond or 0.001 milliseconds. Python on Windows uses +- 16 milliseconds precision due to clock implementation problems due to process interrupts. The timeit module can provide higher resolution if you're measuring execution time.

>>> import time
>>> time.time() #return seconds from epoch
1261367718.971009

Python 3.7 introduces new functions to the time module that provide higher resolution:

>>> import time
>>> time.time_ns()
1530228533161016309
>>> time.time_ns() / (10 ** 9) # convert to floating-point seconds
1530228544.0792289


Related Topics



Leave a reply



Submit