If I have a function called a lot of times in a for loop and this function sometimes is running too much time, how can I use a timer for each call of function(to set and reset the timer each time)?
It looks like:
def theFunction(*args):
#some code (timer is on)
#In this point time is out, break and exit function
#Timer is reseted
for i in range(0,100):
theFunction(*args)
Use the time module like so:
import time
time_start = time.time()
#Do function stuff
time_stop = time.time()
#Check your time now
timed_segment = time_stop - time_start
#Repeat if needed
To run this multiple times in a for loop you will need to append times into a list as it runs like so:
import time
def function():
times_list = []
for x in range(10)
time_start = time.time()
#Do function stuff
time_stop = time.time()
#Check your time now
timed_segment = time_stop - time_start
times_list.append(timed_segment)
#Repeat as many times as needed
return times_list
If you want to break after a certain amount of time you can use a while loop instead like so:
import time
def function():
times_list = []
time_start = time.time()
time_end = time.time()
while time_end - time_start < 10: #after 10 seconds the while loop will time out
#Your function does stuff here
time_end = time.time()
#Next, append times to a list if needed
time_list.append(time_start - time_end)
return times_list
To stop the function after a certain time regardless of where it is, we can use threading like so:
import threading
from time import sleep
def do_stuff():
sleep(10)
print("1 + 2")
return
t = threading.Thread(target=do_stuff)
t.start()
t.join(timeout = 5)
In the above example, calling timeout in join will kill the thread after 5 seconds. We can also put this into a decorator if we plan on reusing it many times like so:
import threading
from time import sleep
def timeout(func):
def inner_func(*nums, **kwargs):
t = threading.Thread(target=func, args=(*nums,))
t.start()
t.join(timeout=5)
return inner_func
#timeout
def do_stuff(a,b):
sleep(3)
print(a+b)
return
do_stuff(1,3)
There is another module called timeit which can measure the execution time of small code snippets. I believe you can use that also. I have never used that module but it should work.
Here is the link to the doc page. Give it a look :: https://docs.python.org/2/library/timeit.html
see How to use timeit module as well
For high re-usability and ease of implementations, I would recommend -
Using decorators -
from time import time
def time_it(func):
def wrapper(*args, **kwargs):
a=time()
func(*args, **kwargs)
print(a-time())
return wrapper
#time_it
def foo(s='this works'):
print(s)
foo()
Using profile.run - https://docs.python.org/2/library/profile.html#module-profile
Related
Is there a way to see how long a script took to execute/complete in VS Code?
I'm looking for a message like:
Program finished in 30ms
Use 'time'
When your script starts:
import time
start_time = time.time()
do something # here your actual code/routine
print("Process finished --- %s seconds ---" % (time.time() - start_time))
You can create a simple decorator function to time your functions.
import time
def decoratortimer(decimal):
def decoratorfunction(f):
def wrap(*args, **kwargs):
time1 = time.monotonic()
result = f(*args, **kwargs)
time2 = time.monotonic()
print('{:s} function took {:.{}f} ms'.format(f.__name__, ((time2-time1)*1000.0), decimal ))
return result
return wrap
return decoratorfunction
#decoratortimer(2)
def callablefunction(name):
print(name)
print(callablefunction('John'))
I suggest using time.monotonic(which is a clock that doesnt go backwards) to increase the accuracy.
Easiest way to achieve this is by purely coding the time to program. perf_counter offers highest accuracy from the time functions.
from time import perf_counter, sleep
def main():
sleep(5)
start_time = perf_counter()
main() # Function to measure
passed_time = perf_counter() - start_time
print(f"It took {passed_time}") # It took 5.007398507999824
For finding your function run time prefer time.perf_counter() over time.time().
See the below link for details
Understanding time.perf_counter() and time.process_time()
You can create your own custom timer using something like this
from time import perf_counter
def f(a1,a2):
return a1 * a2
def timer(f,*args):
start = perf_counter()
f(*args)
return (1000 * (perf_counter()-start)) # this returns time in ms
a1 = np.random.rand(100)
a2 = np.random.rand(100)
np.mean([timer(f,a1,a2) for _ in range(100)]) # average out result for 100 runs
If you are using jupyter notebook use the following
%%timeit
f(a1,a2)
I'm simplifying what I'm trying to achieve as much as possible
I have the following script:
import time, urllib, random
import threading
def get(timeout):
for i in range(2):
time.sleep(timeout)
return urllib.urlopen('http://localhost:9855').read()
def calculate_timeout(total_threads):
pass
if __name__ == '__main__':
total = random.randint(0,400)
for i in xrange(total):
threading.thread(target=get, kwargs={"timeout":calculate_timeout(len(total)}).start()
What I need to do is modify the calculate_timeout function in such a way so that whatever random number comes up,
there won't be more than 60 urllib requests per minute on average.
There's a bevy of rate limiting algorithms posted here including examples for threaded code, the simplest 'imo' I've posted below. The code will create a decorator which you can then use to decorate your get method with.
import time
import threading
from functools import wraps
def rate_limited(max_per_second):
"""
Decorator that make functions not be called faster than
"""
lock = threading.Lock()
min_interval = 1.0 / float(max_per_second)
def decorate(func):
last_time_called = [0.0]
#wraps(func)
def rate_limited_function(*args, **kwargs):
lock.acquire()
elapsed = time.clock() - last_time_called[0]
left_to_wait = min_interval - elapsed
if left_to_wait > 0:
time.sleep(left_to_wait)
lock.release()
ret = func(*args, **kwargs)
last_time_called[0] = time.clock()
return ret
return rate_limited_function
return decorate
I want to make my function run for a particular period like for 5 seconds; how I can do that ?
Like,
def my_function():
while(time == 10 seconds):
......... #run this for 10 seconds
def my_next_function():
while(time == 5 seconds):
......... #run this for 5 seconds
This will definitely help you.
import time
def myfunc():
now=time.time()
timer = 0
while timer != 10:
end = time.time()
timer = round(end-now)
def mynextfunc():
now=time.time()
timer = 0
while timer != 5:
end = time.time()
timer = round(end-now)
myfunc()
print "myfunc() exited after 10 seconds"
mynextfunc()
print "mynextfunc() exited after 5 seconds"
I'd use a <=, rather than a != there. With the round, you'll get integer times, but if something ugly happens, and you skip a second, it'll run forever!
If an individual loop iteration does not take much time:
#!/usr/bin/env python3
from time import monotonic as timer
def my_function():
deadline = timer() + 10
while timer() < deadline:
......... #run this for 10 seconds
def my_next_function():
deadline = timer() + 5
while timer() < deadline:
......... #run this for 5 seconds
Otherwise, see How to limit execution time of a function call in Python.
I'm assuming you want to repeat the whole function until time is up, rather than trying to interrupt the function midway through it time is up (which would be more difficult). One nice solution is to use a decorator:
import time
def repeat(func):
def inner(*args, **kwargs):
if 'repeat_time' in kwargs:
stop = kwargs.pop('repeat_time') + time.time()
while time.time() <= stop:
func(*args, **kwargs)
else:
func(*args, **kwargs)
return inner
#repeat
def my_func():
# ...
my_func() # calls my_func once
my_func(repeat_time=10) # repeatedly calls my_func for 10 seconds
This code assumes you don't want to do anything with the return values from my_func, but can easily be adapted to collect the return values in case you do.
Or simpler if you do not need to pass any parameters to my_func:
def repeat_for(seconds, func):
stop = seconds + time.time()
while time.time() <= stop:
func()
def my_func():
# ...
repeat_for(10, my_func)
I want to write a code which execute a statement specified number of times per second,
Many of you might be familier about the term rate
Here i want rate to be 30 per second
say i want to execute a function 30 times per second for 60 seconds
means rate=30/sec duration=60sec
Can any one tell me is their any api available in python to do the same ?
The sched module is intended for exactly this:
from __future__ import division
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def schedule_it(frequency, duration, callable, *args):
no_of_events = int( duration / frequency )
priority = 1 # not used, lets you assign execution order to events scheduled for the same time
for i in xrange( no_of_events ):
delay = i * frequency
scheduler.enter( delay, priority, callable, args)
def printer(x):
print x
# execute printer 30 times a second for 60 seconds
schedule_it(1/30, 60, printer, 'hello')
scheduler.run()
For a threaded environment, the use of sched.scheduler can be replaced by threading.Timer:
from __future__ import division
import time
import threading
def schedule_it(frequency, duration, callable, *args, **kwargs):
no_of_events = int( duration / frequency )
for i in xrange( no_of_events ):
delay = i * frequency
threading.Timer(delay, callable, args=args, kwargs=kwargs).start()
def printer(x):
print x
schedule_it(5, 10, printer, 'hello')
Try using threading.Timer:
def hello():
print "hello, world"
t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
You can use time.time() to do what you want:
import time
def your_function():
# do something...
while True:
start = time.time() # gives current time in seconds since Jan 1, 1970 (in Unix)
your_function()
while True:
current_time = time.time()
if current_time - start >= 1.0/30.0:
break
This will make sure that the delay between calls of your_function is very close to 1/30 of a second, even if your_function takes some time to run.
There is another way: using Pythons built-in scheduling module, sched. I never used it, so I can't help you there, but have a look at it.
After some time spending i discovered how to do it well i used multiprocessing in python to achieve it
here's my solution
#!/usr/bin/env python
from multiprocessing import Process
import os
import time
import datetime
def sleeper(name, seconds):
time.sleep(seconds)
print "PNAME:- %s"%name
if __name__ == '__main__':
pros={}
processes=[]
i=0
time2=0
time1=datetime.datetime.now()
for sec in range(5):
flag=0
while flag!=1:
time2=datetime.datetime.now()
if (time2-time1).seconds==1:
time1=time2
flag=1
print "Executing Per second"
for no in range(5):
i+=1
pros[i] = Process(target=sleeper, args=("Thread-%d"%i, 1))
j=i-5
for no in range(5):
j+=1
pros[j].start()
j=i-5
for no in range(5):
j+=1
processes.append(pros[j])
for p in processes:
p.join()
I'd like my Python program to run an algorithm for a given number of seconds and then to print the best result so far and to end.
What is the best way to do so?
I tried the following but it did not work(the program kept running after the printing):
def printBestResult(self):
print(self.bestResult)
sys.exit()
def findBestResult(self,time):
self.t = threading.Timer(time, self.printBestResult)
self.t.start()
while(1):
# find best result
Untested code, but something like this?
import time
threshold = 60
start = time.time()
best_run = threshold
while time.time()-start < threshold:
run_start = time.time()
doSomething()
run_time = time.time() - start
if run_time < best_run:
best_run = run_time
On unix, you can use signals -- This code times out after 1 second and counts how many times it iterates through the while loop in that time:
import signal
import sys
def handle_alarm(args):
print args.best_val
sys.exit()
class Foo(object):
pass
self=Foo() #some mutable object to mess with in the loop
self.best_val=0
signal.signal(signal.SIGALRM,lambda *args: handle_alarm(self))
signal.alarm(1) #timeout after 1 second
while True:
self.best_val+=1 # do something to mutate "self" here.
Or, you could easily have your alarm_handler raise an exception which you then catch outside the while loop, printing your best result.
If you want to do this with threads, a good way is to use an Event. Note that signal.alarm won't work in Windows, so I think threading is your best bet unless in that case.
import threading
import time
import random
class StochasticSearch(object):
def __init__(self):
self.halt_event = threading.Event()
def find_best_result(self, duration):
halt_thread = threading.Timer(duration, self.halt_event.set)
halt_thread.start()
best_result = 0
while not self.halt_event.is_set():
result = self.search()
best_result = result if result > best_result else best_result
time.sleep(0.5)
return best_result
def search(self):
val = random.randrange(0, 10000)
print 'searching for something; found {}'.format(val)
return val
print StochasticSearch().find_best_result(3)
You need an exit condition, or the program will run forever (or until it runs out of memory). Add one yourself.