john2x
john2x

Reputation: 23674

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

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.

Upvotes: 1806

Views: 2820330

Answers (30)

Jakob Bagterp
Jakob Bagterp

Reputation: 1324

If you want to use a package, Timer to Python is an easy way to get started with less code. The with statement is a context manager that automatically starts and stops the clock:

from timer import Timer

with Timer():
    # Insert your code here

How it appears in the terminal:

Elapsed time: 1.23 seconds

Function Decorator

If you want to be more granular and measure performance of individual functions, it's more elegant with a @function_timer decorator, since the timer will be triggered each time the function is called and the clock will stop automatically when the function is finished. For example:

from timer import function_timer

@function_timer()
def my_function():
    # Insert your code here

my_function()

How it appears in the terminal:

Elapsed time: 1.23 seconds for thread MY_FUNCTION

About Timer for Python

In full disclosure, I'm the author of Timer for Python. It's a lightweight package that makes measuring time and performance easy.

If you want to customise the default output, you can set different thread name or decimals. For example:

Elapsed time: 0.12345 seconds for thread CUSTOM

Upvotes: 1

SkruDJ
SkruDJ

Reputation: 167

More easy and comfortable solve

>>> import subprocess, os
>>> subprocess.check_output(f'ps -o lstart= -p {os.getpid()}', shell=True).decode('UTF-8')
'Mon May  6 13:24:54 2024\n'

Upvotes: 0

Pedro Lobito
Pedro Lobito

Reputation: 99001

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

Upvotes: 6

Matt
Matt

Reputation: 6330

For the data folks using Jupyter Notebook

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

%%time
sum(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

333283335000

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.

Upvotes: 34

Mamed Shahmaliyev
Mamed Shahmaliyev

Reputation: 331

Below is one line code to quickly get execution time:

from time import perf_counter, sleep
_, _, exec_time = (s := perf_counter()), sleep(1), perf_counter()-s
print(exec_time)

Upvotes: 2

DGS
DGS

Reputation: 381

I think this is the best and easiest way to do it:

from time import monotonic

start_time = monotonic()
# something
print(f"Run time {monotonic() - start_time} seconds")

Or with a decorator:

from time import monotonic
    
def record_time(function):
    def wrap(*args, **kwargs):
        start_time = monotonic()
        function_return = function(*args, **kwargs)
        print(f"Run time {monotonic() - start_time} seconds")
        return function_return
    return wrap

@record_time
def your_function():
    # something

Upvotes: 18

NELSON JOSEPH
NELSON JOSEPH

Reputation: 85

The problem I encountered while finding the running time of two different methods for finding all the prime numbers <= a number. when a user input was taken in the program.

WRONG APPROACH

#Sample input for a number 20 
#Sample output [2, 3, 5, 7, 11, 13, 17, 19]
#Total Running time = 0.634 seconds

import time

start_time = time.time()

#Method 1 to find all the prime numbers <= a Number

# Function to check whether a number is prime or not.
def prime_no(num):
if num<2:
    return False
else:
    for i in range(2, num//2+1):
        if num % i == 0:
            return False
    return True

#To print all the values <= n
def Prime_under_num(n):
    a = [2]
    if n <2:
        print("None")
    elif n==2:
        print(2)
    else:
"Neglecting all even numbers as even numbers won't be prime in order to reduce the time complexity."
        for i in range(3, n+1, 2):   
            if prime_no(i):
                a.append(i)
        print(a)


"When Method 1 is only used outputs of running time for different inputs"
#Total Running time = 2.73761 seconds #n = 100
#Total Running time = 3.14781 seconds #n = 1000
#Total Running time = 8.69278 seconds #n = 10000
#Total Running time = 18.73701 seconds #n = 100000

#Method 2 to find all the prime numbers <= a Number

def Prime_under_num(n):
    a = [2]
    if n <2:
        print("None")
    elif n==2:
        print(2)
    else:
        for i in range(3, n+1, 2):   
            if n%i ==0:
                pass
            else:
                a.append(i)
        print(a)

"When Method 2 is only used outputs of running time for different inputs"
# Total Running time = 2.75935 seconds #n = 100
# Total Running time = 2.86332 seconds #n = 1000
# Total Running time = 4.59884 seconds #n = 10000
# Total Running time = 8.55057 seconds #n = 100000

if __name__ == "__main__" :
    n = int(input())
    Prime_under_num(n)
    print("Total Running time = {:.5f} seconds".format(time.time() - start_time))

The different running time obtained for all the above cases are wrong. For problems where we are taking an input, we have to start the time only after taking the input. Here the time taken by the user to type the input is also calculated along with the running time.

CORRECT APPROACH

We have to remove the start_time = time.time() from the begining and add it in the main block.

if __name__ == "__main__" :
    n = int(input())
    start_time = time.time()
    Prime_under_num(n)
    print("Total Running time = {:.3f} seconds".format(time.time() - start_time))

Thus the output for the each of the two methods when used alone will be as follows:-

# Method 1

# Total Running time = 0.00159 seconds #n = 100
# Total Running time = 0.00506 seconds #n = 1000
# Total Running time = 0.22987 seconds #n = 10000
# Total Running time = 18.55819 seconds #n = 100000

# Method 2

# Total Running time = 0.00011 seconds #n = 100
# Total Running time = 0.00118 seconds #n = 1000
# Total Running time = 0.00302 seconds #n = 10000
# Total Running time = 0.01450 seconds #n = 100000

Now we can see there is a significant difference in total running time when compared with WRONG APPROACH. Even though the method 2 is performing better than method 1 in the both approach first approach(WRONG APPROACH) is wrong.

Upvotes: 0

mmik
mmik

Reputation: 5991

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

Upvotes: 0

Sasha Vasserfirer
Sasha Vasserfirer

Reputation: 69

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())

Upvotes: 4

Nicolargo
Nicolargo

Reputation: 134

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()
   ...

Upvotes: -2

Nikita Tonkoskur
Nikita Tonkoskur

Reputation: 1499

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

Upvotes: 20

Md. Imrul Kayes
Md. Imrul Kayes

Reputation: 963

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")

Upvotes: 58

newacct
newacct

Reputation: 122499

import time

start_time = time.clock()
main()
print(time.clock() - start_time, "seconds")

time.clock() returns the processor time, which allows us to calculate only the time used by this process (on Unix anyway). The documentation says "in any case, this is the function to use for benchmarking Python or timing algorithms"

Upvotes: 127

Nick Legend
Nick Legend

Reputation: 1058

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

Upvotes: 5

Mitul Panchal
Mitul Panchal

Reputation: 632

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)

Upvotes: 8

Ravi Kumar
Ravi Kumar

Reputation: 802

Just use the timeit module. It works with both Python 2 and Python 3.

import timeit

start = timeit.default_timer()

# All the program statements
stop = timeit.default_timer()
execution_time = stop - start

print("Program Executed in "+str(execution_time)) # It returns time in seconds

It returns in seconds and you can have your execution time. It is simple, but you should write these in thew main function which starts program execution. If you want to get the execution time even when you get an error then take your parameter "Start" to it and calculate there like:

def sample_function(start,**kwargs):
     try:
         # Your statements
     except:
         # except statements run when your statements raise an exception
         stop = timeit.default_timer()
         execution_time = stop - start
         print("Program executed in " + str(execution_time))

Upvotes: 61

Hafez Ahmad
Hafez Ahmad

Reputation: 185

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")

Upvotes: 9

Amar Kumar
Amar Kumar

Reputation: 2646

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

Upvotes: 6

user 923227
user 923227

Reputation: 2715

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

Upvotes: 22

steveha
steveha

Reputation: 76745

In Linux or Unix:

$ time python yourprogram.py

In Windows, see this StackOverflow question: How do I measure execution time of a command on the Windows command line?

For more verbose output,

$ time -v python yourprogram.py
    Command being timed: "python3 yourprogram.py"
    User time (seconds): 0.08
    System time (seconds): 0.02
    Percent of CPU this job got: 98%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.10
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 9480
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 1114
    Voluntary context switches: 0
    Involuntary context switches: 22
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

Upvotes: 305

hans
hans

Reputation: 1112

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.

Upvotes: 12

jfs
jfs

Reputation: 414725

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.

$ python -mtimeit -n1 -r1 -t -s "from your_module import main" "main()"

It runs your_module.main() function one time and print the elapsed time using time.time() function as a timer.

To emulate /usr/bin/time in Python see Python subprocess with /usr/bin/time: how to capture timing info but ignore all other output?.

To measure CPU time (e.g., don't include time during time.sleep()) for each function, you could use profile module (cProfile on Python 2):

$ python3 -mprofile your_module.py

You could pass -p to timeit command above if you want to use the same timer as profile module uses.

See How can you profile a Python script?

Upvotes: 12

Kushal Ghosh
Kushal Ghosh

Reputation: 81

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())

Upvotes: 3

Rui Carvalho
Rui Carvalho

Reputation: 3476

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.

Upvotes: 1

Tao Wang
Tao Wang

Reputation: 714

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'

Upvotes: 9

Yu Jiaao
Yu Jiaao

Reputation: 4714

Use line_profiler.

line_profiler will profile the time individual lines of code take to execute. The profiler is implemented in C via Cython in order to reduce the overhead of profiling.

from line_profiler import LineProfiler
import random

def do_stuff(numbers):
    s = sum(numbers)
    l = [numbers[i]/43 for i in range(len(numbers))]
    m = ['hello'+str(numbers[i]) for i in range(len(numbers))]

numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()

The results will be:

Timer unit: 1e-06 s

Total time: 0.000649 s
File: <ipython-input-2-2e060b054fea>
Function: do_stuff at line 4

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     4                                           def do_stuff(numbers):
     5         1           10     10.0      1.5      s = sum(numbers)
     6         1          186    186.0     28.7      l = [numbers[i]/43 for i in range(len(numbers))]
     7         1          453    453.0     69.8      m = ['hello'+str(numbers[i]) for i in range(len(numbers))]

Upvotes: 9

Utkarsh Dhawan
Utkarsh Dhawan

Reputation: 324

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)

Upvotes: 6

Manu
Manu

Reputation: 112

The time of a Python program's execution measure could be inconsistent depending on:

  • Same program can be evaluated using different algorithms
  • Running time varies between algorithms
  • Running time varies between implementations
  • Running time varies between computers
  • Running time is not predictable based on small inputs

This is because the most effective way is using the "Order of Growth" and learn the Big "O" notation to do it properly.

Anyway, you can try to evaluate the performance of any Python program in specific machine counting steps per second using this simple algorithm: adapt this to the program you want to evaluate

import time

now = time.time()
future = now + 10
step = 4 # Why 4 steps? Because until here already four operations executed
while time.time() < future:
    step += 3 # Why 3 again? Because a while loop executes one comparison and one plus equal statement
step += 4 # Why 3 more? Because one comparison starting while when time is over plus the final assignment of step + 1 and print statement
print(str(int(step / 10)) + " steps per second")

Upvotes: 3

H0R5E
H0R5E

Reputation: 65

To use metakermit's updated answer for Python 2.7, you will require the monotonic package.

The code would then be as follows:

from datetime import timedelta
from monotonic import monotonic

start_time = monotonic()
end_time = monotonic()
print(timedelta(seconds=end_time - start_time))

Upvotes: 1

B.Kocis
B.Kocis

Reputation: 2020

In IPython, "timeit" any script:

def foo():
    %run bar.py
timeit foo()

Upvotes: 9

Related Questions