Необходимо чтобы в одну секунду цикл выполнялся не более 20 раз.
Как можно этого добиться?
Необходимо чтобы в одну секунду цикл выполнялся не более 20 раз.
Как можно этого добиться?
Можно выполнить 20 итераций одну за другой и подождать пока секунда закончится (если необходимо), а затем повторить сначала (псевдо-код):
from time import monotonic as timer
N = 20 # the number of iterations
INTERVAL = 1 # seconds
while True:
start = timer() # remember when the loop starts
for _ in range(N):
do_something()
elapsed = timer() - start # find out how long it takes
if elapsed < INTERVAL:
time.sleep(INTERVAL - elapsed) # wait until the interval ends
Таким образом за секунду происходит не более 20 итераций и время в ожидании только по необходимости происходит.
Если хочется равномерно распределить каждую итерацию, чтобы каждая итерация начиналась бы на границе INTERVAL / N секунд (1/20 ~ 50 миллисекунд), то при условии, что do_something() занимает меньше 50 миллисекунд это легко сделать:
interval = INTERVAL / N
for _ in range(N):
do_something()
time.sleep(interval - timer() % interval)
Этот и другие варианты, которые для других случаев могут быть более подходящими, см. в Как правильно сделать временный цикл?
В случае, если исполнение идёт в нескольких потока/процессах, то можно использовать семафор, который по времени ограничивает количество доступных токенов:
from threading import Thread
def rate_limited_work(rate_limit=RatedSemaphore(N, INTERVAL)):
while True:
with rate_limit:
do_something()
for _ in range(N):
Thread(target=rate_limited_work).start()
Код выполняет одновременно N вызовов rate_limited_work функции, каждый в своём потоке. rate_limit семафор гарантирует, что не более N вызовов do_something() будут за INTERVAL секунд (не более 20 вызовов за секунду для данного вопроса).
Если работа в do_something() ограничена I/O или происходит в Си расширениях, которые GIL отпускают, то потоки могут эффективно ресурсы машины использовать в CPython.
time.clock() - в Unix, возвращает текущее время. В Windows, возвращает время, прошедшее с момента первого вызова данной функции.(В миллисекундах)
В одной секунде тысяча миллисекунд.
import time
first_time = time.clock
all_time = 0
for i in range(1000000000000):
all_time += time.clock()
if all_time > 1000:
break
print(all_time)