Reputation: 137
Could someone please give me some help with limiting a loop to N iterations per minute in Python.
Lets say I have
limit = 5
for items in recvData:
# > limit iterations in past minute? -> sleep for 60 seconds from last iterations before proceeding? #
... do work ...
How would I do the time check / sleeping to give the correct flow. I'm not worried about blocking the executing thread/process while it waits.
Thanks
Upvotes: 0
Views: 4613
Reputation: 483
This would be the most appropriate answer : What's a good rate limiting algorithm?
I especially like the second answer using the decorator!
Upvotes: 0
Reputation: 70984
It should be noted that this is not "hard real time" code. this will be off slightly because of OS scheduling and the like. That being said, unless you know that you need hard real time, this should suffice.
import time
limit = 5
starttime = time.time()
for i, item in enumerate(recvData):
if not i + 1 % limit:
sleeptime =starttime + 60 - time.time()
if sleeptime > 0:
time.sleep(sleeptime)
starttime = time.time()
#processing code
Upvotes: 3
Reputation: 1962
This very much depends on the type of work you're doing inside the loop and on how accurate you want this mechanism to work.
ATM I can come up with 2 possible schemes:
1 - iterationTime
afterwards. Depending on the standard deviation of your single loop execution times both scheme can work quite well, but if the execution times are very varying, neither of them will. Also, if you want evenly distributed loop cycles and not only keep the average/min you have to distribute the sleep-s and do one after each iteration.
I am not familiar enough with Python to know how expensive is to query the time and what other Python-specific issues might pop up with sleep-ing, though.
Upvotes: 0
Reputation: 123612
Use grouper
from the itertools
recipes, combined with a time check.
import itertools, datetime, time
limit = 5
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
for items in grouper(limit, recvData):
prev_minute = datetime.datetime.now().minute
for item in items:
# do stuff
_, _, _, _, minute, second, _ = datetime.datetime.now()
if minute == prev_minute:
time.sleep( 60 - second )
Upvotes: 0