How can I time a code segment for testing performance with Pythons timeit?
You can use time.time()
or time.clock()
before and after the block you want to time.
import time
t0 = time.time()
code_block
t1 = time.time()
total = t1-t0
This method is not as exact as timeit
(it does not average several runs) but it is straightforward.
time.time()
(in Windows and Linux) and time.clock()
(in Linux) are not precise enough for fast functions (you get total = 0). In this case or if you want to average the time elapsed by several runs, you have to manually call the function multiple times (As I think you already do in you example code and timeit does automatically when you set its number argument)
import time
def myfast():
code
n = 10000
t0 = time.time()
for i in range(n): myfast()
t1 = time.time()
total_n = t1-t0
In Windows, as Corey stated in the comment, time.clock()
has much higher precision (microsecond instead of second) and is preferred over time.time()
.
How to measure time taken between lines of code in python?
If you want to measure CPU time, can use time.process_time()
for Python 3.3 and above:
import time
start = time.process_time()
# your code here
print(time.process_time() - start)
First call turns the timer on, and second call tells you how many seconds have elapsed.
There is also a function time.clock()
, but it is deprecated since Python 3.3 and will be removed in Python 3.8.
There are better profiling tools like timeit
and profile
, however time.process_time() will measure the CPU time and this is what you're are asking about.
If you want to measure wall clock time instead, use time.time()
.
How to time functions with timeit and save results
Function timeit
does not have direct access to the global variables. You must provide the dictionary of the global variabes through the globals
keyword. Since the variable ps
is first read in the timed statement, it is by default considered local. Mark it as global:
# This part is only for testing
ps = []
def f(x,y): return x+y
A, B = 10, 11
timeit('global ps; ps += [f(A,B)]', number=1, globals=globals())
Run setup code exactly once for different test statements using timeit
The easiest way to achieve this is to put the setup code into a module setup.py
, and then use
"from setup import name_1, name_2, name_3"
as setup
parameter to timeit.timeit()
. (Note that wildcard imports won't work correctly in that situation.)
If you don't want to use a separate module, put the code in the main module and use
"from __main__ import name_1, name_2, name_3"
Show timeit progress
You can create your subclass of timeit.Timer
that uses tqdm
to track the total iterations performed.
from timeit import Timer, default_number
from tqdm import tqdm
import itertools
import gc
class ProgressTimer(Timer):
def timeit(self, number=default_number):
"""Time 'number' executions of the main statement.
To be precise, this executes the setup statement once, and
then returns the time it takes to execute the main statement
a number of times, as a float measured in seconds. The
argument is the number of times through the loop, defaulting
to one million. The main statement, the setup statement and
the timer function to be used are passed to the constructor.
"""
# wrap the iterator in tqdm
it = tqdm(itertools.repeat(None, number), total=number)
gcold = gc.isenabled()
gc.disable()
try:
timing = self.inner(it, self.timer)
finally:
if gcold:
gc.enable()
# the tqdm bar sometimes doesn't flush on short timers, so print an empty line
print()
return timing
To use this object, we just need to pass in the script we want to run. You can either define it as a string (like below) or you can simply open the file for reading and read to a variable.
py_setup = 'import numpy as np'
py_script = """
x = np.random.rand(1000)
x.sum()
"""
pt = ProgressTimer(py_script, setup=py_setup)
pt.timeit()
# prints / returns:
100%|███████████████████████████████████████████████| 1000000/1000000 [00:13<00:00, 76749.68it/s]
13.02982600001269
Using timeit to time algorithms without timing already sorted or setup
Your understanding is correct. However, there are some issues that could be improved.
Firstly, you usually want to measure only one algorithm at a time. If you measure each algorithm separately you can compare the two and get more accurate data. Also, I would stick to measuring it on the same graph multiple times and then average the time to get one more accurate (you can use copy.deepcopy()
to make duplicates of the graph). Then do this on each of the graphs you have. Since each algorithm may be more efficient on different types of graphs (you would lose this information completely if measured as you propose).
Secondly, since timeit
can repeat the measured operation multiple times but the setup is done only once before any measurement starts (see the docs) you would measure the algorithm on already traversed (or sorted as you put it) graphs. Which you correctly point out.
As a solution, I suggest manually timing the runs using the time.perf_counter_ns()
. The code for measuring the bellmanFord algorithm could look as such:
import time
import copy
"""
Measures bellman ford algorithm ran on a *graph* *repetitions* number of times.
Returns time measured
"""
def measure_bellman_ford(repetitions, graph):
graphs = [copy.deepcopy(graph) for x in range(repetitions)]
# make measurements
start = time.perf_counter_ns()
for idx in range(repetitions):
graphs[idx].bellmanFord(0)
end = time.perf_counter_ns()
return (end - start) / repetitions
Related Topics
"Python" Not Recognized as a Command
What Is the Standard Way to Add N Seconds to Datetime.Time in Python
How to Check If the String Is Empty
Display a Decimal in Scientific Notation
Rename Multiple Files in a Directory in Python
Generate Random Numbers Summing to a Predefined Value
How to Get the Named Parameters from a Url Using Flask
How to Convert a String of Bytes into an Int
Importerror: Dll Load Failed: %1 Is Not a Valid Win32 Application. But the Dll's Are There
Append Multiple Values for One Key in a Dictionary
How to Delete Rows from a Pandas Dataframe Based on a Conditional Expression
How to Get Text with Selenium Webdriver in Python
How to Get the Path of the Current Executed File in Python