Reputation: 23674
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
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
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
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
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
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
code_to_test
.number
argument specifies the amount of times the code should repeat.Upvotes: 6
Reputation: 6330
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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:
Upvotes: 6
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
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
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
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
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
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
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
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
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
Reputation: 112
The time of a Python program's execution measure could be inconsistent depending on:
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
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