1705

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.

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
john2x
  • 22,546
  • 16
  • 57
  • 95

39 Answers39

2894

The simplest way in Python:

import time
start_time = time.time()
main()
print("--- %s seconds ---" % (time.time() - start_time))

This assumes that your program takes at least a tenth of second to run.

Prints:

--- 0.764891862869 seconds ---
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rogeriopvl
  • 51,659
  • 8
  • 55
  • 58
  • 113
    this calculates the real time though (including time used by other programs) so it will seem to take more time when your computer is busy doing other stuff – newacct Oct 13 '09 at 01:23
  • 67
    on Windows, do the same thing, but use time.clock() instead of time.time(). You will get slightly better accuracy. – Corey Goldberg Oct 13 '09 at 14:02
  • 70
    I recommend doing `round(time.time() - start_time, 2)` (or whatever decimal you want), I was getting scientific numbers back like 1.24e-5. – ThorSummoner Feb 06 '15 at 17:49
  • 48
    @ThorSummoner: you probably want `'%.2f'` instead of `round()` here. – jfs Mar 03 '15 at 08:41
  • 9
    @CoreyGoldberg: if you want `time.clock()` on Windows and `time.time()` on other systems then use `timeit.default_timer()`. It is `time.perf_counter()` on the recent Python version. Though for large intervals (days), `time.time()` may produce better results everywhere. – jfs Mar 03 '15 at 08:45
  • 26
    There is a big flaw in this method. If system time changes while the program is running (like sync with time server) then this method wont work or may even break the code (negative duration...) – Gilad Nov 09 '16 at 15:53
  • 12
    `time.clock()` is deprecated in python 3.7+ and you'll get warnings. Starting with python 3.3 you are better off doing the same thing, but using `time.process_time()` or `time.perf_counter()`. `perf_counter` is if you want to isolate a single function, and `process_time` captures the real time for the CPU on the whole system. – Marc Maxmeister Jan 30 '20 at 20:28
  • 1
    I see this is limited to 1/10 second or more. If you need high resolution timestamps to measure milliseconds or microseconds, here's some: https://stackoverflow.com/questions/38319606/how-to-get-millisecond-and-microsecond-resolution-timestamps-in-python/38319607#38319607 – Gabriel Staples Apr 05 '20 at 05:09
  • If there is an error occurs on `main()`it won't print the time i takes. Should I run it under `try-catch-finally`? – alper May 21 '20 at 12:40
  • 2
    Use `time.monotonic()` to avoid bugs due to changing system time / NTP. – Błażej Michalik Oct 07 '22 at 13:20
  • @jfs will you elaborate why? – Saeed Aug 10 '23 at 02:58
  • @Saeed do you mean why time.time over perf_counter for periods counted in days? I remember at the time that perf_counter or it's analog overflows (at least on some impl.) – jfs Aug 11 '23 at 14:52
  • @jfs no, I meant why you recommended '%.2f' instead of round()? – Saeed Aug 11 '23 at 22:56
  • 1
    @Saeed to get the desired formatting (round returns a float here, not str). – jfs Aug 14 '23 at 17:02
284

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
vipulgupta2048
  • 141
  • 1
  • 14
steveha
  • 74,789
  • 21
  • 92
  • 117
259

I put this timing.py module into my own site-packages directory, and just insert import timing at the top of my module:

import atexit
from time import clock

def secondsToStr(t):
    return "%d:%02d:%02d.%03d" % \
        reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
            [(t*1000,),1000,60,60])

line = "="*40
def log(s, elapsed=None):
    print line
    print secondsToStr(clock()), '-', s
    if elapsed:
        print "Elapsed time:", elapsed
    print line
    print

def endlog():
    end = clock()
    elapsed = end-start
    log("End Program", secondsToStr(elapsed))

def now():
    return secondsToStr(clock())

start = clock()
atexit.register(endlog)
log("Start Program")

I can also call timing.log from within my program if there are significant stages within the program I want to show. But just including import timing will print the start and end times, and overall elapsed time. (Forgive my obscure secondsToStr function, it just formats a floating point number of seconds to hh:mm:ss.sss form.)

Note: A Python 3 version of the above code can be found here or here.

Community
  • 1
  • 1
PaulMcG
  • 62,419
  • 16
  • 94
  • 130
  • 11
    This is a real clean solution that also works if you press Ctrl-C to stop the program. – sorin Jun 09 '10 at 14:31
  • great solution I will definitely use it and create a timing decorator to identify bottleneck functions – c24b May 15 '14 at 22:32
  • 14
    For Python 3 add `from functools import reduce` at the top and put brackets around each print statement. Works great! – PowerApp101 Apr 05 '15 at 02:02
  • 3
    @PowerApp101 - Thanks - Nicojo's answer provides a Py3-friendly version of this module. – PaulMcG Apr 05 '15 at 04:21
  • 12
    Note: time.clock() is "Deprecated since version 3.3: The behaviour of this function depends on the platform: use perf_counter() [with time slept] or process_time() [without time slept] instead, depending on your requirements, to have a well defined behaviour." – mab Oct 19 '15 at 13:12
  • I like this solution, but it produces an ugly warning due to unused import. Other than that, works great, although it can be simplified to fewer lines – Roman Rdgz Oct 27 '16 at 07:37
  • if u r using sublime text it gives the execution time of a python program in the terminal – Rishi Ratan Pandey Jan 02 '22 at 07:30
149

I like the output the datetime module provides, where time delta objects show days, hours, minutes, etc. as necessary in a human-readable way.

For example:

from datetime import datetime
start_time = datetime.now()
# do your work here
end_time = datetime.now()
print('Duration: {}'.format(end_time - start_time))

Sample output e.g.

Duration: 0:00:08.309267

or

Duration: 1 day, 1:51:24.269711

As J.F. Sebastian mentioned, this approach might encounter some tricky cases with local time, so it's safer to use:

import time
from datetime import timedelta
start_time = time.monotonic()
end_time = time.monotonic()
print(timedelta(seconds=end_time - start_time))
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
metakermit
  • 21,267
  • 15
  • 86
  • 95
  • 2
    @phansen: you could use `timedelta(seconds=time.monotonic()-start)` here (or `time.time()` if the interval is large). [Don't subtract naive datetime objects that represent local time; local time is not monotonous](http://stackoverflow.com/a/26313848/4279) – jfs Mar 03 '15 at 08:31
  • OK, you mean like `start_time = time.monotonic(); end_time = time.monotonic(); timedelta(seconds=end_time - start_time)`. I trust you're right, but then you also have to format it, as you get back `datetime.timedelta(0, 0, 76)`. Also, seems the monotonic method was only added in Python 3. – metakermit Mar 04 '15 at 10:23
  • Ah, OK. I see you can pass it to `str()` to make it "human". I'll update the answer, thanks. – metakermit Mar 04 '15 at 10:24
122
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"

Shidouuu
  • 368
  • 4
  • 14
newacct
  • 119,665
  • 29
  • 163
  • 224
  • 18
    time.time() is best used on *nix. time.clock() is best used on Windows. – Corey Goldberg Oct 13 '09 at 14:03
  • I believe this can not be used to calculate "only the time used by this process" because it uses system time and will be effected by other system processes? Correct me if I'm wrong about this :) – AnnanFay Jul 23 '13 at 10:49
  • 25
    Note: time.clock() is "Deprecated since version 3.3: The behaviour of this function depends on the platform: use perf_counter() [with time slept] or process_time() [without time slept] instead, depending on your requirements, to have a well defined behaviour." – mab Oct 19 '15 at 13:14
86

I really like Paul McGuire's answer, but I use Python 3. So for those who are interested: here's a modification of his answer that works with Python 3 on *nix (I imagine, under Windows, that clock() should be used instead of time()):

#python3
import atexit
from time import time, strftime, localtime
from datetime import timedelta

def secondsToStr(elapsed=None):
    if elapsed is None:
        return strftime("%Y-%m-%d %H:%M:%S", localtime())
    else:
        return str(timedelta(seconds=elapsed))

def log(s, elapsed=None):
    line = "="*40
    print(line)
    print(secondsToStr(), '-', s)
    if elapsed:
        print("Elapsed time:", elapsed)
    print(line)
    print()

def endlog():
    end = time()
    elapsed = end-start
    log("End Program", secondsToStr(elapsed))

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

If you find this useful, you should still up-vote his answer instead of this one, as he did most of the work ;).

Georgy
  • 12,464
  • 7
  • 65
  • 73
Nicojo
  • 1,043
  • 8
  • 8
  • 1
    I found `timedelta(seconds=t).total_seconds()` helpful. – nu everest Nov 28 '15 at 12:38
  • Can you explain what these functions do? what is s in the log command? what is atexit? – SumNeuron Dec 10 '16 at 16:35
  • @SumNeuron, in short, these functions print out the execution time of the program you use it with. s is the first argument to log, and should be a string. log is a function that prints out the timing info. atexit is a python module that lets you register functions to be called at the exit of the program. – Nicojo Dec 10 '16 at 21:07
  • @Nicojo Very helpful. I have a question on how can i use this code to test for example the time for a loop execution. suppose I have a function incuding a loop, and i want to get the time spent by this loop – moudi Jun 13 '19 at 18:48
  • @moudi The top answer to this question is your best bet. Just set the start time right before you loop, and calculate the elapsed time at the exit of the loop. – Nicojo Jun 14 '19 at 19:08
  • Can I use it to time a section of code within a larger module? I've tried it and it seems it only stop the clock once the "main" stops execution. – ruslaniv Apr 28 '20 at 11:53
  • Sorry if this is a stupid question but where do I have to put my function inside this code to measure it's execution time? What's the placeholder here? – Jan Kowalski Jun 29 '20 at 13:16
82

You can use the Python profiler cProfile to measure CPU time and additionally how much time is spent inside each function and how many times each function is called. This is very useful if you want to improve performance of your script without knowing where to start. This answer to another Stack Overflow question is pretty good. It's always good to have a look in the documentation too.

Here's an example how to profile a script using cProfile from a command line:

$ python -m cProfile euler048.py

1007 function calls in 0.061 CPU seconds

Ordered by: standard name
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.061    0.061 <string>:1(<module>)
 1000    0.051    0.000    0.051    0.000 euler048.py:2(<lambda>)
    1    0.005    0.005    0.061    0.061 euler048.py:2(<module>)
    1    0.000    0.000    0.061    0.061 {execfile}
    1    0.002    0.002    0.053    0.053 {map}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler objects}
    1    0.000    0.000    0.000    0.000 {range}
    1    0.003    0.003    0.003    0.003 {sum}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jacwah
  • 2,727
  • 2
  • 21
  • 42
58

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))
djamaile
  • 695
  • 3
  • 12
  • 30
Ravi Kumar
  • 772
  • 7
  • 8
47

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")
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Md. Imrul Kayes
  • 819
  • 6
  • 13
42

time.clock()

Deprecated since version 3.3: The behavior of this function depends on the platform: use perf_counter() or process_time() instead, depending on your requirements, to have a well-defined behavior.

time.perf_counter()

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.

time.process_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.

start = time.process_time()
... do something
elapsed = (time.process_time() - start)
Yas
  • 4,957
  • 2
  • 41
  • 24
30

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.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matt
  • 5,800
  • 1
  • 44
  • 40
21

The following snippet prints elapsed time in a nice human readable <HH:MM:SS> format.

import time
from datetime import timedelta

start_time = time.time()

#
# Perform lots of computations.
#

elapsed_time_secs = time.time() - start_time

msg = "Execution took: %s secs (Wall clock time)" % timedelta(seconds=round(elapsed_time_secs))

print(msg)    
Sandeep
  • 28,307
  • 3
  • 32
  • 24
  • 3
    all the way down here one finds the most sane answer ('sane' meaning relying as much as possible on built-ins and therefore the least typing). – ijoseph Jul 20 '17 at 17:25
21

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
user 923227
  • 2,528
  • 4
  • 27
  • 46
18

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
Nikita Tonkoskur
  • 1,440
  • 1
  • 16
  • 28
13
from time import time
start_time = time()
...
end_time = time()
time_taken = end_time - start_time # time_taken is in seconds
hours, rest = divmod(time_taken,3600)
minutes, seconds = divmod(rest, 60)
The6thSense
  • 8,103
  • 8
  • 31
  • 65
Qina Yan
  • 1,206
  • 10
  • 5
11

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?

jfs
  • 399,953
  • 195
  • 994
  • 1,670
11

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.

hans
  • 1,043
  • 12
  • 33
10

I liked Paul McGuire's answer too and came up with a context manager form which suited my needs more.

import datetime as dt
import timeit

class TimingManager(object):
    """Context Manager used with the statement 'with' to time some execution.

    Example:

    with TimingManager() as t:
       # Code to time
    """

    clock = timeit.default_timer

    def __enter__(self):
        """
        """
        self.start = self.clock()
        self.log('\n=> Start Timing: {}')

        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        """
        self.endlog()

        return False

    def log(self, s, elapsed=None):
        """Log current time and elapsed time if present.
        :param s: Text to display, use '{}' to format the text with
            the current time.
        :param elapsed: Elapsed time to display. Dafault: None, no display.
        """
        print s.format(self._secondsToStr(self.clock()))

        if(elapsed is not None):
            print 'Elapsed time: {}\n'.format(elapsed)

    def endlog(self):
        """Log time for the end of execution with elapsed time.
        """
        self.log('=> End Timing: {}', self.now())

    def now(self):
        """Return current elapsed time as hh:mm:ss string.
        :return: String.
        """
        return str(dt.timedelta(seconds = self.clock() - self.start))

    def _secondsToStr(self, sec):
        """Convert timestamp to h:mm:ss string.
        :param sec: Timestamp.
        """
        return str(dt.datetime.fromtimestamp(sec))
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gall
  • 1,595
  • 1
  • 14
  • 22
9

In IPython, "timeit" any script:

def foo():
    %run bar.py
timeit foo()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
B.Kocis
  • 1,954
  • 20
  • 19
  • If you use `%%timeit` (two percents), you can save defining function foo, as demonstrated by [this related answer](https://stackoverflow.com/a/25005695/2375855). – ojdo Jul 01 '21 at 16:04
9

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))]
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yu Jiaao
  • 4,444
  • 5
  • 44
  • 57
9

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'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tao Wang
  • 704
  • 8
  • 5
8

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")
Hafez Ahmad
  • 175
  • 2
  • 7
  • time.perf_counter(): float - 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 consecutive calls is valid. https://docs.python.org/3/library/time.html#time.perf_counter – James McGuigan Jun 17 '20 at 09:16
7

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)
swateek
  • 6,735
  • 8
  • 34
  • 48
Mitul Panchal
  • 592
  • 5
  • 7
6

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)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Utkarsh Dhawan
  • 324
  • 3
  • 9
6

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
Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268
6

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

Georgy
  • 12,464
  • 7
  • 65
  • 73
Amar Kumar
  • 2,392
  • 2
  • 25
  • 33
6

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
DGS
  • 121
  • 2
  • 3
5

There is a timeit module which can be used to time the execution times of Python code.

It has detailed documentation and examples in Python documentation, 26.6. timeit — Measure execution time of small code snippets.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alfie
  • 2,706
  • 1
  • 14
  • 28
  • OP explicitly mentions `timeit` in the question. The question is how it can be used here (or should it be used here and what are the alternatives). Here's [possible answer](http://stackoverflow.com/a/28827752/4279). – jfs Mar 03 '15 at 09:06
4

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
Nick Legend
  • 789
  • 1
  • 7
  • 21
4

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

This is Paul McGuire's answer that works for me. Just in case someone was having trouble running that one.

import atexit
from time import clock

def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        value = next(it)
    else:
        value = initializer
    for element in it:
        value = function(value, element)
    return value

def secondsToStr(t):
    return "%d:%02d:%02d.%03d" % \
        reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
            [(t*1000,),1000,60,60])

line = "="*40
def log(s, elapsed=None):
    print (line)
    print (secondsToStr(clock()), '-', s)
    if elapsed:
        print ("Elapsed time:", elapsed)
    print (line)

def endlog():
    end = clock()
    elapsed = end-start
    log("End Program", secondsToStr(elapsed))

def now():
    return secondsToStr(clock())

def main():
    start = clock()
    atexit.register(endlog)
    log("Start Program")

Call timing.main() from your program after importing the file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Saurabh Rana
  • 3,350
  • 2
  • 19
  • 22
3

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")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Manu
  • 112
  • 4
3

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())
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 6
    __main__:1: 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 – JayRizzo Jul 05 '19 at 16:20
1

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))
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
H0R5E
  • 65
  • 6
1

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rui Carvalho
  • 3,376
  • 1
  • 21
  • 18
0

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
Md Mazedul Islam Khan
  • 5,318
  • 4
  • 40
  • 66
0

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.

  • Method 2 I used for returning all prime numbers <= a number is wrong it actually returns all the odd numbers <= a number. The case is mentioned only for errors that happened while checking the total running time, – NELSON JOSEPH Oct 06 '22 at 03:43
0

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

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()
   ...
Nicolargo
  • 124
  • 1
  • 1
  • 9