timing block of code in Python without putting it in a function - python

I'd like to time a block of code without putting it in a separate function. for example:
def myfunc:
# some code here
t1 = time.time()
# block of code to time here
t2 = time.time()
print "Code took %s seconds." %(str(t2-t1))
however, I'd like to do this with the timeit module in a cleaner way, but I don't want to make a separate function for the block of code.
thanks.

You can do this with the with statement. For example:
import time
from contextlib import contextmanager
#contextmanager
def measureTime(title):
t1 = time.clock()
yield
t2 = time.clock()
print '%s: %0.2f seconds elapsed' % (title, t2-t1)
To be used like this:
def myFunc():
#...
with measureTime('myFunc'):
#block of code to time here
#...

You can set up a variable to refer to the code block you want to time by putting that block inside Python's triple quotes. Then use that variable when instantiating your timeit object. Somewhat following an example from the Python timeit docs, I came up with the following:
import timeit
code_block = """\
total = 0
for cnt in range(0, 1000):
total += cnt
print total
"""
tmr = timeit.Timer(stmt=code_block)
print tmr.timeit(number=1)
Which for me printed:
499500
0.000341892242432
(Where 499500 is the output of the timed block, and 0.000341892242432 is the time running.)

According with Skilldrick answer there is a silly module that I think can help: BlockLogginInator.
import time
from blocklogginginator import logblock # logblock is the alias
with logblock(name='one second'):
""""
Our code block.
"""
time.sleep(1)
>>> Block "one second" started
>>> Block "one second" ended (1.001)

Related

How can I get the time execution of the code? [duplicate]

So in Java, we can do How to measure time taken by a function to execute
But how is it done in python? To measure the time start and end time between lines of code?
Something that does this:
import some_time_library
starttime = some_time_library.some_module()
code_tobe_measured()
endtime = some_time_library.some_module()
time_taken = endtime - starttime
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().
You can also use time library:
import time
start = time.time()
# your code
# end
print(f'Time: {time.time() - start}')
With a help of a small convenience class, you can measure time spent in indented lines like this:
with CodeTimer():
line_to_measure()
another_line()
# etc...
Which will show the following after the indented line(s) finishes executing:
Code block took: x.xxx ms
UPDATE: You can now get the class with pip install linetimer and then from linetimer import CodeTimer. See this GitHub project.
The code for above class:
import timeit
class CodeTimer:
def __init__(self, name=None):
self.name = " '" + name + "'" if name else ''
def __enter__(self):
self.start = timeit.default_timer()
def __exit__(self, exc_type, exc_value, traceback):
self.took = (timeit.default_timer() - self.start) * 1000.0
print('Code block' + self.name + ' took: ' + str(self.took) + ' ms')
You could then name the code blocks you want to measure:
with CodeTimer('loop 1'):
for i in range(100000):
pass
with CodeTimer('loop 2'):
for i in range(100000):
pass
Code block 'loop 1' took: 4.991 ms
Code block 'loop 2' took: 3.666 ms
And nest them:
with CodeTimer('Outer'):
for i in range(100000):
pass
with CodeTimer('Inner'):
for i in range(100000):
pass
for i in range(100000):
pass
Code block 'Inner' took: 2.382 ms
Code block 'Outer' took: 10.466 ms
Regarding timeit.default_timer(), it uses the best timer based on OS and Python version, see this answer.
Putting the code in a function, then using a decorator for timing is another option. (Source) The advantage of this method is that you define timer once and use it with a simple additional line for every function.
First, define timer decorator:
import functools
import time
def timer(func):
#functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
value = func(*args, **kwargs)
end_time = time.perf_counter()
run_time = end_time - start_time
print("Finished {} in {} secs".format(repr(func.__name__), round(run_time, 3)))
return value
return wrapper
Then, use the decorator while defining the function:
#timer
def doubled_and_add(num):
res = sum([i*2 for i in range(num)])
print("Result : {}".format(res))
Let's try:
doubled_and_add(100000)
doubled_and_add(1000000)
Output:
Result : 9999900000
Finished 'doubled_and_add' in 0.0119 secs
Result : 999999000000
Finished 'doubled_and_add' in 0.0897 secs
Note: I'm not sure why to use time.perf_counter instead of time.time. Comments are welcome.
I always prefer to check time in hours, minutes and seconds (%H:%M:%S) format:
from datetime import datetime
start = datetime.now()
# your code
end = datetime.now()
time_taken = end - start
print('Time: ',time_taken)
output:
Time: 0:00:00.000019
I was looking for a way how to output a formatted time with minimal code, so here is my solution. Many people use Pandas anyway, so in some cases this can save from additional library imports.
import pandas as pd
start = pd.Timestamp.now()
# code
print(pd.Timestamp.now()-start)
Output:
0 days 00:05:32.541600
I would recommend using this if time precision is not the most important, otherwise use time library:
%timeit pd.Timestamp.now() outputs 3.29 µs ± 214 ns per loop
%timeit time.time() outputs 154 ns ± 13.3 ns per loop
You can try this as well:
from time import perf_counter
t0 = perf_counter()
...
t1 = perf_counter()
time_taken = t1 - t0
Let me add a little more to https://stackoverflow.com/a/63665115/7412781 solution.
Removed dependency on functools.
Used process time taken time.process_time() instead of absolute counter of time.perf_counter() because the process can be context switched out via kernel.
Used the raw function pointer print to get the correct class name as well.
This is the decorator code.
import time
def decorator_time_taken(fnc):
def inner(*args):
start = time.process_time()
ret = fnc(*args)
end = time.process_time()
print("{} took {} seconds".format(fnc, round((end - start), 6)))
return ret
return inner
This is the usage sample code. It's checking if 193939 is prime or not.
class PrimeBrute:
#decorator_time_taken
def isPrime(self, a):
for i in range(a-2):
if a % (i+2) == 0: return False
return True
inst = PrimeBrute()
print(inst.isPrime(193939))
This is the output.
<function PrimeBrute.isPrime at 0x7fc0c6919ae8> took 0.015789 seconds
True
Use timeit module to benchmark your performance:
def test():
print("test")
emptyFunction()
for i in [x for x in range(10000)]:
i**i
def emptyFunction():
pass
if __name__ == "__main__":
import timeit
print(timeit.timeit("test()", number = 5, globals = globals()))
#print(timeit.timeit("test()", setup = "from __main__ import test",
# number = 5))
the first parameter defines the piece of code which we want to execute test in this case & number defines how many times you want to repeat the execution.
Output:
test
test
test
test
test
36.81822113099952
Using the module time, we can calculate unix time at the start of the function and at the end of a function. Here is how the code might look like:
from time import time as unix
This code imports time.time which allows us to calculate unix time.
from time import sleep
This is not mandatory, but I am also importing time.sleep for one of the demonstrations.
START_TIME = unix()
This is what calculates unix time and puts it in a variable. Remember, the function unix is not an actual function. I imported time.time as unix, so if you did not put as unix in the first import, you will need to use time.time().
After this, we put whichever function or code we want.
At the end of the code snippet we put
TOTAL_TIME = unix()-START_TIME
This line of code does two things: It calculates unix time at the end of the function, and using the variable START_TIME from before, we calculate the amount of time it took to execute the code snippet.
We can then use this variable wherever we want, including for a print() function.
print("The snippet took {} seconds to execute".format(TOTAL_TIME))
Here I wrote a quick demonstration code that has two experiments as a demonstration. (Fully commented)
from time import time as unix # Import the module to measure unix time
from time import sleep
# Here are a few examples:
# 1. Counting to 100 000
START_TIME = unix()
for i in range(0, 100001):
print("Number: {}\r".format(i), end="")
TOTAL_TIME = unix() - START_TIME
print("\nFinal time (Expirement 1): {} s\n".format(TOTAL_TIME))
# 2. Precision of sleep
for i in range(10):
START_TIME = unix()
sleep(0.1)
TOTAL_TIME = unix() - START_TIME
print("Sleep(0.1): Index: {}, Time: {} s".format(i,TOTAL_TIME))
Here was my output:
Number: 100000
Final time (Expirement 1): 16.666812419891357 s
Sleep(0.1): Index: 0, Time: 0.10014867782592773 s
Sleep(0.1): Index: 1, Time: 0.10016226768493652 s
Sleep(0.1): Index: 2, Time: 0.10202860832214355 s
Sleep(0.1): Index: 3, Time: 0.10015869140625 s
Sleep(0.1): Index: 4, Time: 0.10014724731445312 s
Sleep(0.1): Index: 5, Time: 0.10013675689697266 s
Sleep(0.1): Index: 6, Time: 0.10014677047729492 s
Sleep(0.1): Index: 7, Time: 0.1001439094543457 s
Sleep(0.1): Index: 8, Time: 0.10044598579406738 s
Sleep(0.1): Index: 9, Time: 0.10014700889587402 s
>
import datetime
#this code before computation
%%timeit
~code~

Breaking up a print statement Python with intermediate process

When i run the script below, the print statement(s) appear at the same time. I would like the first print statement to display, then the loop to execute, then the run time to print.
Is there an additional statement I need to include?
import time
def main():
Time = time.clock()
print("Counting to 100,000,000:", end = "")
for i in range(1,100000000):
a = 3
print(" -- Time: ", time.clock() - Time)
if __name__ == "__main__":
main()
There is a buffer in Python's standard output. This means that data you want to write (as in print()) is sometimes stored and then written in one go - as you are experiencing here.
To override this, just call sys.stdout.flush() which "flushes" everything already in this buffer out.
So to apply this to your code, it would look something like:
import time, sys
def main():
Time = time.clock()
print("Counting to 100,000,000:", end = "")
sys.stdout.flush()
for i in range(1,100000000):
a = 3
print(" -- Time: ", time.clock() - Time)
if __name__ == "__main__":
main()
which ran as expected for me (producing the following output) with the second part coming through later.
Counting to 100,000,000: -- Time: 4.796258999999999

how to measure execution time of python code

need help for this code
import timeit
mysetup=""
mycode='''
def gener():
...my code here...
return x
'''
# timeit statement
print (timeit.timeit(setup = mysetup,
stmt = mycode,
number = 1000000))
print("done")
As result I got 0.0008606994517737132
As I read this unit is in "seconds"
So my funtion executed 1 million time in 0.8 ms ?
I think this is not real, too fast.
I also tried basic option
start = time.time()
my code here
end = time.time()
print(end - start)
and got 0.23901081085205078 for one time execution it seems a little slow...
So what I'm I doing wrong ?
Thanks
The way you have defined this in mycode for the timeit method, all that is going to happen is the function gener will be defined, not run. You need to run the function in your code block in order to report time taken for execution.
As for what length of time is reasonable (too fast/too slow) it very much depends on what your code is doing. But I suspect you have executed the function in method 2 and only defined it in method 1, hence the discrepancy.
Edit: example code
To illustrate the difference, in the example below the block code1 just defines a function, it does not execute it. The block code2 defines and executes the function.
import timeit
code1 = '''
def gener():
time.sleep(0.01)
'''
code2 = '''
def gener():
time.sleep(0.01)
gener()
'''
We should expect running time.sleep(0.01) 100 times to take approximately 1 second. Running timeit for code1 returns ~ 10^-5 seconds, because the function gener is not actually being called:
timeit.timeit(stmt=code1, number=100)
Running timeit for code2 returns the expected result of ~1 second:
timeit.timeit(stmt=code2, number=100)
Further to this, the point of the setup argument is to do setup (the parts of the code which are not meant to be timed). If you want timeit to capture the execution time of gener, you should use this:
import timeit
setup = '''
def gener():
time.sleep(0.01)
'''
stmt = "gener()"
timeit.timeit(setup=setup, stmt=stmt, number=100)
This returns the time taken to run gener 100 times, not including the time taken to define it.
Here is a general way to measure time of code snippets.
import time
class timer(object):
"""
A simple timer used to time blocks of code. Usage as follows:
with timer("optional_name"):
some code ...
some more code
"""
def __init__(self, name=None):
self.name = name
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, *args):
self.end = time.time()
self.interval = self.end - self.start
if self.name:
print("{} - Elapsed time: {:.4f}s".format(self.name, self.interval))
else:
print("Elapsed time: {:.4f}s".format(self.interval))
gist available here: https://gist.github.com/Jakobovski/191b9e95ac964b61e8abc7436111d1f9
If you want to time a function timeit can be used like so:
# defining some function you want to time
def test(n):
s = 0
for i in range(n):
s += i
return s
# defining a function which runs the function to be timed with desired input arguments
timed_func = lambda : test(1000)
# the above is done so that we have a function which takes no input arguments
N = 10000 # number of repeats
time_per_run = timeit.timeit(stmt=timed_func, number=N)/N
For your case you can do:
# defining some function you want to time
def gener():
...my code here...
return x
N = 1000000 # number of repeats
time_per_run = timeit.timeit(stmt=gener, number=N)/N
Any importing of libraries can be done globally before calling the timeit function and timeit will use the globally imported libraries
e.g.
import numpy as np
# defining some function you want to time
def gener():
...my code here...
x = np.sqrt(y)
return x
N = 1000000 # number of repeats
time_per_run = timeit.timeit(stmt=gener, number=N)/N
Working code
# importing the required module
import timeit
# code snippet to be executed only once
mysetup = '''
from collections import OrderedDict
def gener():
some lines of code here
return x'''
# code snippet whose execution time is to be measured
mycode="gener()"
# timeit statement
nb=10
print("The code run {} time in: ".format(nb ))
print("{} secondes".format(timeit.timeit(setup = mysetup,
stmt = mycode,
number = nb)))
print("done")
execution time was almost the same with the one got below
start = time.time()
my code here
end = time.time()
print(end - start)
0.23 sec with timeit and with the basic measurement code above 0.24 ,they both fluctuate...
So thanks, question resolved

Timing python function

(Python 2.7.8, Windows)
there is so many questions already about this particular subject, but I cannot seem to get any of them working.
So, what I'm trying to accomplish is timing how long a function takes to execute.
I have functions.py and main.py in following fashion:
#functions.py
def function(list):
does something
return list
...
#main.py
import functions
...stuff...
while:
list = gets list from file
functions.function(list) <--- this needs to get timed
Now I tried time.time() the start and end points first, but it's not accurate enough (difference tends to be 0.0), and after some googling it seems that this isn't the way to go anyway. Apparently what I should use(?) is timeit module. However I cannot understand how to get the function into it.
Any help?
As you mentioned, there's a Python module made for this very task, timeit. Its syntax, while a little idiosyncratic, is quite easy to understand:
timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000)
stmt is the function call to be measured, in your case: functions.function(list)
setup is the code you need to create the context necessary for stmt to execute, in your case: import functions; list = gets list from file
number is how many time timeit would run stmt to find its average execution time. You might want to change the number, since calling your function a million times might take a while.
tl;dr:
timeit.timeit(stmt='functions.function(list)', setup='import functions; list = gets list from file', number=100)
you see this demo: time.time
>>> def check(n):
... start = time.time()
... for x in range(n):
... pass
... stop = time.time()
... return stop-start
...
>>> check(1000)
0.0001239776611328125
>>> check(10000)
0.0012159347534179688
>>> check(100)
1.71661376953125e-05
the above function returns hum much time in sec taken by for for n loops.
so the algorithm is:
start = time.time()
# your stuff
stop = time.time()
time_taken = stop - start
start = timeit.default_timer()
my_function()
elapsed = timeit.default_timer() - start

Accurate timing of functions in python

I'm programming in python on windows and would like to accurately measure the time it takes for a function to run. I have written a function "time_it" that takes another function, runs it, and returns the time it took to run.
def time_it(f, *args):
start = time.clock()
f(*args)
return (time.clock() - start)*1000
i call this 1000 times and average the result. (the 1000 constant at the end is to give the answer in milliseconds.)
This function seems to work but i have this nagging feeling that I'm doing something wrong, and that by doing it this way I'm using more time than the function actually uses when its running.
Is there a more standard or accepted way to do this?
When i changed my test function to call a print so that it takes longer, my time_it function returns an average of 2.5 ms while the cProfile.run('f()') returns and average of 7.0 ms. I figured my function would overestimate the time if anything, what is going on here?
One additional note, it is the relative time of functions compared to each other that i care about, not the absolute time as this will obviously vary depending on hardware and other factors.
Use the timeit module from the Python standard library.
Basic usage:
from timeit import Timer
# first argument is the code to be run, the second "setup" argument is only run once,
# and it not included in the execution time.
t = Timer("""x.index(123)""", setup="""x = range(1000)""")
print t.timeit() # prints float, for example 5.8254
# ..or..
print t.timeit(1000) # repeat 1000 times instead of the default 1million
Instead of writing your own profiling code, I suggest you check out the built-in Python profilers (profile or cProfile, depending on your needs): http://docs.python.org/library/profile.html
You can create a "timeme" decorator like so
import time
def timeme(method):
def wrapper(*args, **kw):
startTime = int(round(time.time() * 1000))
result = method(*args, **kw)
endTime = int(round(time.time() * 1000))
print(endTime - startTime,'ms')
return result
return wrapper
#timeme
def func1(a,b,c = 'c',sleep = 1):
time.sleep(sleep)
print(a,b,c)
func1('a','b','c',0)
func1('a','b','c',0.5)
func1('a','b','c',0.6)
func1('a','b','c',1)
This code is very inaccurate
total= 0
for i in range(1000):
start= time.clock()
function()
end= time.clock()
total += end-start
time= total/1000
This code is less inaccurate
start= time.clock()
for i in range(1000):
function()
end= time.clock()
time= (end-start)/1000
The very inaccurate suffers from measurement bias if the run-time of the function is close to the accuracy of the clock. Most of the measured times are merely random numbers between 0 and a few ticks of the clock.
Depending on your system workload, the "time" you observe from a single function may be entirely an artifact of OS scheduling and other uncontrollable overheads.
The second version (less inaccurate) has less measurement bias. If your function is really fast, you may need to run it 10,000 times to damp out OS scheduling and other overheads.
Both are, of course, terribly misleading. The run time for your program -- as a whole -- is not the sum of the function run-times. You can only use the numbers for relative comparisons. They are not absolute measurements that convey much meaning.
If you want to time a python method even if block you measure may throw, one good approach is to use with statement. Define some Timer class as
import time
class Timer:
def __enter__(self):
self.start = time.clock()
return self
def __exit__(self, *args):
self.end = time.clock()
self.interval = self.end - self.start
Then you may want to time a connection method that may throw. Use
import httplib
with Timer() as t:
conn = httplib.HTTPConnection('google.com')
conn.request('GET', '/')
print('Request took %.03f sec.' % t.interval)
__exit()__ method will be called even if the connection request thows. More precisely, you'd have you use try finally to see the result in case it throws, as with
try:
with Timer() as t:
conn = httplib.HTTPConnection('google.com')
conn.request('GET', '/')
finally:
print('Request took %.03f sec.' % t.interval)
More details here.
This is neater
from contextlib import contextmanager
import time
#contextmanager
def timeblock(label):
start = time.clock()
try:
yield
finally:
end = time.clock()
print ('{} : {}'.format(label, end - start))
with timeblock("just a test"):
print "yippee"
Similar to #AlexMartelli's answer
import timeit
timeit.timeit(fun, number=10000)
can do the trick.

Categories