60

I'm new to Python, and confused by the date/time documentation. I want to compute the time that it takes to perform a computation.

In java, I would write:

long timeBefore = System.currentTimeMillis();
doStuff();
long timeAfter = System.currentTimeMillis();
elapsed time = timeAfter - timeBefore;

I'm sure it's even easier in Python. Can anyone help?

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
Eric Wilson
  • 57,719
  • 77
  • 200
  • 270
  • 1
    Specifically, what *Python* code are you looking at? – S.Lott Sep 23 '09 at 10:28
  • I wasn't looking at Python code, I was preparing to write it. By the way, I'm intrigued by your Building Skills in Python book, I'll be checking it out. – Eric Wilson Sep 23 '09 at 12:29
  • 1
    related: [Measure time elapsed in Python?](http://stackoverflow.com/q/7370801/4279) – jfs Jan 07 '16 at 04:43

9 Answers9

95

Equivalent in python would be:

>>> import time
>>> tic = time.clock()
>>> toc = time.clock()
>>> toc - tic

If you are trying to find the best performing method then you should probably have a look at timeit.

sanyassh
  • 8,100
  • 13
  • 36
  • 70
SilentGhost
  • 307,395
  • 66
  • 306
  • 293
  • 1
    indeed, prob `clock` is better for this sort of measurements. – SilentGhost Sep 23 '09 at 10:30
  • Thanks for providing the equivalent. I'll have to look into `timeit` in the future, but for my current small exercise this will be sufficient. – Eric Wilson Sep 23 '09 at 10:33
  • 8
    Note that `time.clock` doesn't do the same on all platforms. More notably, on unix it returns processor time, not clock time. – nosklo Sep 23 '09 at 11:59
  • 34
    `time.clock()` is deprecated since Python 3.3 and prints a warning since Python 3.7. The recommended functions are now `time.process_time()` and `time.perf_counter()`. See https://docs.python.org/3/library/time.html#time.clock –  Jul 01 '18 at 09:37
  • 1
    Can this answer please be updated for python >=3.3? Please replace time.clock() with .perf_counter() or .process_time() – Sander van den Oord Sep 04 '22 at 11:26
39

Building on and updating a number of earlier responses (thanks: SilentGhost, nosklo, Ramkumar) a simple portable timer would use timeit's default_timer():

>>> import timeit
>>> tic=timeit.default_timer()
>>> # Do Stuff
>>> toc=timeit.default_timer()
>>> toc - tic #elapsed time in seconds

This will return the elapsed wall clock (real) time, not CPU time. And as described in the timeit documentation chooses the most precise available real-world timer depending on the platform.

ALso, beginning with Python 3.3 this same functionality is available with the time.perf_counter performance counter. Under 3.3+ timeit.default_timer() refers to this new counter.

For more precise/complex performance calculations, timeit includes more sophisticated calls for automatically timing small code snippets including averaging run time over a defined set of repetitions.

Bryan P
  • 5,900
  • 5
  • 34
  • 49
15

You can implement two tic() and tac() functions, where tic() captures the time which it is called, and tac() prints the time difference since tic() was called. Here is a short implementation:

import time

_start_time = time.time()

def tic():
    global _start_time 
    _start_time = time.time()

def tac():
    t_sec = round(time.time() - _start_time)
    (t_min, t_sec) = divmod(t_sec,60)
    (t_hour,t_min) = divmod(t_min,60) 
    print('Time passed: {}hour:{}min:{}sec'.format(t_hour,t_min,t_sec))

Now in your code you can use it as:

tic()
do_some_stuff()
tac()

and it will, for example, output:

Time passed: 0hour:7min:26sec

See also:

user263387
  • 457
  • 4
  • 5
15

For Python 3.3 and later time.process_time() is very nice:

import time

t = time.process_time()
#do some stuff
elapsed_time = time.process_time() - t
Michael Dorner
  • 17,587
  • 13
  • 87
  • 117
  • 6
    Note this ignores any `time.sleep()` time delays in the code, I just tried testing it with `time.sleep()` for a minute and got quite confused! E.g. if you want to repeat the process at precise time intervals like webscraping, can measure elapsed_time then add on appropriate `time.sleep()` delay – Will Croxford Feb 20 '19 at 16:05
  • Spoke too soon, Actually I just used selenium package to open website login, send message, can see it's taking 20 seconds or more just for selenium to fill out the message in text box, but get 0.125 as the elapsed time from `process_time()` before getting the URL to time at end typing message, not sure what's going on, docs mentions time.sleep() delays ignored by process_time, but filling the box is normal processing time surely, sending several send_keys() calls from selenium to do this. – Will Croxford Feb 20 '19 at 16:20
  • @WillCroxford I encountered similar with process_time(). time() gave a more accurate number for the wait I experienced before my functions executed. – Sam Doidge Oct 26 '21 at 18:16
6

Use timeit. http://docs.python.org/library/timeit.html

artagnon
  • 3,609
  • 3
  • 23
  • 26
2

I also got a requirement to calculate the process time of some code lines. So I tried the approved answer and I got this warning.

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

So python will remove time.clock() from Python 3.8. You can see more about it from issue #13270. This warning suggest two function instead of time.clock(). In the documentation also mention about this warning in-detail in time.clock() section.

Deprecated since version 3.3, will be removed in version 3.8: The behaviour of this function depends on the platform: use perf_counter() or process_time() instead, depending on your requirements, to have a well defined behaviour.

Let's look at in-detail both functions.


Return the value (in fractional seconds) of a performance counter, i.e. a clock with the highest available resolution to measure a short duration. It does include time elapsed during sleep and is system-wide. The reference point of the returned value is undefined, so that only the difference between the results of two calls is valid.

New in version 3.3.

Changed in version 3.10: On Windows, the function is now system-wide.

So if you want it as nanoseconds, you can use time.perf_counter_ns() and if your code consist with time.sleep(secs), it will also count. Ex:-

import time


def func(x):
    time.sleep(5)
    return x * x


lst = [1, 2, 3]
tic = time.perf_counter()
print([func(x) for x in lst])
toc = time.perf_counter()
print(toc - tic)

# [1, 4, 9]
# 15.0041916 --> output including 5 seconds sleep time

Return the value (in fractional seconds) of the sum of the system and user CPU time of the current process. It does not include time elapsed during sleep. It is process-wide by definition. The reference point of the returned value is undefined, so that only the difference between the results of two calls is valid.

Use process_time_ns() to avoid the precision loss caused by the float type.

New in version 3.3.

So if you want it as nanoseconds, you can use time.process_time_ns() and if your code consist with time.sleep(secs), it won't count. Ex:-

import time


def func(x):
    time.sleep(5)
    return x * x


lst = [1, 2, 3]
tic = time.process_time()
print([func(x) for x in lst])
toc = time.process_time()
print(toc - tic)

# [1, 4, 9]
# 0.0 --> output excluding 5 seconds sleep time

Please note both time.perf_counter_ns() and time.process_time_ns() come up with Python 3.7 onward.

Kushan Gunasekera
  • 7,268
  • 6
  • 44
  • 58
1
python -m timeit -h
pixelbeat
  • 30,615
  • 9
  • 51
  • 60
1

If all you want is the time between two points in code (and it seems that's what you want) I have written tic() toc() functions ala Matlab's implementation. The basic use case is:

tic()

''' some code that runs for an interesting amount of time '''

toc()

# OUTPUT:
# Elapsed time is: 32.42123 seconds

Super, incredibly easy to use, a sort of fire-and-forget kind of code. It's available on Github's Gist https://gist.github.com/tyleha/5174230

tyleha
  • 3,319
  • 1
  • 17
  • 25
  • `time.time()` is not monotonic and must not be used to measure time intervals – Grief May 30 '16 at 23:12
  • 3
    Interesting, you are correct. Glad to learn something new! Additionally, thanks for taking the time to dig up this 3 yr old answer, read through my Gist, downvote me, and yet not provide a suggestion of an alternative or an explanation why it's non-monotonic! For those of you who are looking to actually improve your code and learn, some research of my own suggests you should use [`time.monotonic`](https://www.python.org/dev/peps/pep-0418/#time-monotonic), available in Python 3.3+ (which I now use). `time.time` is not monotonic because it relies on system time, which can be modified mid-run – tyleha May 31 '16 at 20:21
1

For some further information on how to determine the processing time, and a comparison of a few methods (some mentioned already in the answers of this post) - specifically, the difference between:

start = time.time()

versus the now obsolete (as of 3.3, time.clock() is deprecated)

start = time.clock()

see this other article on Stackoverflow here:

Python - time.clock() vs. time.time() - accuracy?

If nothing else, this will work good:

start = time.time()

... do something

elapsed = (time.time() - start)
Community
  • 1
  • 1
ntk4
  • 1,247
  • 1
  • 13
  • 18