How do I get time of a Python program's execution?

Viewed 2112138

I have a command line program in Python that takes a while to finish. I want to know the exact time it takes to finish running.

I've looked at the timeit module, but it seems it's only for small snippets of code. I want to time the whole program.

36 Answers

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

import time
start_time = time.perf_counter ()
for x in range(1, 100):
    print(x)
end_time = time.perf_counter ()
print(end_time - start_time, "seconds")

For the data folks using Jupyter Notebook

In a cell, you can use Jupyter's %%time magic command to measure the execution time:

%%time
[ x**2 for x in range(10000)]

Output

CPU times: user 4.54 ms, sys: 0 ns, total: 4.54 ms
Wall time: 4.12 ms

This will only capture the execution time of a particular cell. If you'd like to capture the execution time of the whole notebook (i.e. program), you can create a new notebook in the same directory and in the new notebook execute all cells:

Suppose the notebook above is called example_notebook.ipynb. In a new notebook within the same directory:

# Convert your notebook to a .py script:
!jupyter nbconvert --to script example_notebook.ipynb

# Run the example_notebook with -t flag for time
%run -t example_notebook

Output

IPython CPU timings (estimated):
  User   :       0.00 s.
  System :       0.00 s.
Wall time:       0.00 s.

Similar to the response from @rogeriopvl I added a slight modification to convert to hour minute seconds using the same library for long running jobs.

import time
start_time = time.time()
main()
seconds = time.time() - start_time
print('Time Taken:', time.strftime("%H:%M:%S",time.gmtime(seconds)))

Sample Output

Time Taken: 00:00:08

For functions, I suggest using this simple decorator I created.

def timeit(method):
    def timed(*args, **kwargs):
        ts = time.time()
        result = method(*args, **kwargs)
        te = time.time()
        if 'log_time' in kwargs:
            name = kwargs.get('log_name', method.__name__.upper())
            kwargs['log_time'][name] = int((te - ts) * 1000)
        else:
            print('%r  %2.22f ms' % (method.__name__, (te - ts) * 1000))
        return result
    return timed

@timeit
def foo():
    do_some_work()

# foo()
# 'foo'  0.000953 ms

I was having the same problem in many places, so I created a convenience package horology. You can install it with pip install horology and then do it in the elegant way:

from horology import Timing

with Timing(name='Important calculations: '):
    prepare()
    do_your_stuff()
    finish_sth()

will output:

Important calculations: 12.43 ms

Or even simpler (if you have one function):

from horology import timed

@timed
def main():
    ...

will output:

main: 7.12 h

It takes care of units and rounding. It works with python 3.6 or newer.

I used a very simple function to time a part of code execution:

import time
def timing():
    start_time = time.time()
    return lambda x: print("[{:.2f}s] {}".format(time.time() - start_time, x))

And to use it, just call it before the code to measure to retrieve function timing, and then call the function after the code with comments. The time will appear in front of the comments. For example:

t = timing()
train = pd.read_csv('train.csv',
                        dtype={
                            'id': str,
                            'vendor_id': str,
                            'pickup_datetime': str,
                            'dropoff_datetime': str,
                            'passenger_count': int,
                            'pickup_longitude': np.float64,
                            'pickup_latitude': np.float64,
                            'dropoff_longitude': np.float64,
                            'dropoff_latitude': np.float64,
                            'store_and_fwd_flag': str,
                            'trip_duration': int,
                        },
                        parse_dates = ['pickup_datetime', 'dropoff_datetime'],
                   )
t("Loaded {} rows data from 'train'".format(len(train)))

Then the output will look like this:

[9.35s] Loaded 1458644 rows data from 'train'

I tried and found time difference using the following scripts.

import time

start_time = time.perf_counter()
[main code here]
print (time.perf_counter() - start_time, "seconds")

Timeit is a class in Python used to calculate the execution time of small blocks of code.

Default_timer is a method in this class which is used to measure the wall clock timing, not CPU execution time. Thus other process execution might interfere with this. Thus it is useful for small blocks of code.

A sample of the code is as follows:

from timeit import default_timer as timer

start= timer()

# Some logic

end = timer()

print("Time taken:", end-start)

You do this simply in Python. There is no need to make it complicated.

import time

start = time.localtime()
end = time.localtime()
"""Total execution time in minutes$ """
print(end.tm_min - start.tm_min)
"""Total execution time in seconds$ """
print(end.tm_sec - start.tm_sec)

Later answer, but I use the built-in timeit:

import timeit
code_to_test = """
a = range(100000)
b = []
for i in a:
    b.append(i*2)
"""
elapsed_time = timeit.timeit(code_to_test, number=500)
print(elapsed_time)
# 10.159821493085474

  • Wrap all your code, including any imports you may have, inside code_to_test.
  • number argument specifies the amount of times the code should repeat.
  • Demo

First, install humanfriendly package by opening Command Prompt (CMD) as administrator and type there - pip install humanfriendly

Code:

from humanfriendly import format_timespan
import time
begin_time = time.time()
# Put your code here
end_time = time.time() - begin_time
print("Total execution time: ", format_timespan(end_time))

Output:

enter image description here

Following this answer created a simple but convenient instrument.

import time
from datetime import timedelta

def start_time_measure(message=None):
    if message:
        print(message)
    return time.monotonic()

def end_time_measure(start_time, print_prefix=None):
    end_time = time.monotonic()
    if print_prefix:
        print(print_prefix + str(timedelta(seconds=end_time - start_time)))
    return end_time

Usage:

total_start_time = start_time_measure()    
start_time = start_time_measure('Doing something...')
# Do something
end_time_measure(start_time, 'Done in: ')
start_time = start_time_measure('Doing something else...')
# Do something else
end_time_measure(start_time, 'Done in: ')
end_time_measure(total_start_time, 'Total time: ')

The output:

Doing something...
Done in: 0:00:01.218000
Doing something else...
Done in: 0:00:01.313000
Total time: 0:00:02.672000

This is the simplest way to get the elapsed time for the program:

Write the following code at the end of your program.

import time
print(time.clock())

I use tic and toc from ttictoc.

pip install ttictoc

Then you can use in your script:

from ttictoc import tic,toc
tic()

# foo()

print(toc())

If you want to measure time in microseconds, then you can use the following version, based completely on the answers of Paul McGuire and Nicojo - it's Python 3 code. I've also added some colour to it:

import atexit
from time import time
from datetime import timedelta, datetime


def seconds_to_str(elapsed=None):
    if elapsed is None:
        return datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
    else:
        return str(timedelta(seconds=elapsed))


def log(txt, elapsed=None):
    colour_cyan = '\033[36m'
    colour_reset = '\033[0;0;39m'
    colour_red = '\033[31m'
    print('\n ' + colour_cyan + '  [TIMING]> [' + seconds_to_str() + '] ----> ' + txt + '\n' + colour_reset)
    if elapsed:
        print("\n " + colour_red + " [TIMING]> Elapsed time ==> " + elapsed + "\n" + colour_reset)


def end_log():
    end = time()
    elapsed = end-start
    log("End Program", seconds_to_str(elapsed))


start = time()
atexit.register(end_log)
log("Start Program")

log() => function that prints out the timing information.

txt ==> first argument to log, and its string to mark timing.

atexit ==> Python module to register functions that you can call when the program exits.

By default, Linux or Unix system (tested on macOS) comes with the time command on the terminal that you can use to run the Python script and get the real, user, sys time information for the execution of the running script.

However, the default output isn't very clear (at least for me), and the default time command doesn't even take any options as arguments to format the output. That's because there are two versions of time - one is built into bash that provides just the minimal version and another one is located on /usr/bin/time.

The /usr/bin/time command accepts additional arguments like -al, -h, -p, and -o. My favorite is -p which shows the output in a new line like the following:

real 2.18
user 17.92
sys 2.71

I define the following Python decorator:

def profile(fct):
  def wrapper(*args, **kw):
    start_time = time.time()
    ret = fct(*args, **kw)
    print("{} {} {} return {} in {} seconds".format(args[0].__class__.__name__,
                                                    args[0].__class__.__module__,
                                                    fct.__name__,
                                                    ret,
                                                    time.time() - start_time))
    return ret
  return wrapper

and use it on functions or class/methods:

@profile
def main()
   ...
Related