Выполнять инструкцию каждые N итераций в Python

У меня очень длинный цикл, и я бы хотел проверить статус каждые N итераций, в моем конкретном случае у меня есть цикл из 10 миллионов элементов, и я хочу напечатать короткий отчет каждые миллионные итерации.

Итак, в настоящее время я делаю (n - итерационный счетчик):

if (n % 1000000==0):
    print('Progress report...')

но я обеспокоен тем, что замедляю процесс, вычисляя модуль на каждой итерации, поскольку одна итерация длится всего несколько миллисекунд.

Есть ли лучший способ сделать это? Или я не должен вообще волноваться о работе модуля?

Ответ 1

Как сохранить счетчик и сбросить его до нуля, когда вы достигнете желаемого номера? Добавление и проверка равенства выполняется быстрее, чем по модулю.

printcounter = 0

# Whatever a while loop is in Python
while (...):   
    ...
    if (printcounter == 1000000):
        print('Progress report...')
        printcounter = 0
    ...
    printcounter += 1

Хотя вполне возможно, что компилятор уже делает какую-то оптимизацию для вас уже... но это может дать вам спокойствие.

Ответ 2

Неужели это замедляется? Вы должны попробовать и посмотреть сами. Это не будет значительным замедлением, но если говорить о наносекундах, это может быть значительным. В качестве альтернативы вы можете преобразовать один цикл из 10 миллионов в два меньших цикла:

m = 1000000
for i in range(10):
    for i in range(m):
        // do sth
    print("Progress report")

Ответ 3

Трудно понять, как ваша система будет оптимизировать ваш код без тестирования.

Вы можете упростить реляционную часть, осознав, что нуль оценивается как false.

if(not N % 10000000)
   do stuff

Ответ 4

Sup, dawg? Свяжитесь со мной, если вам нужен дополнительный комментарий/объяснение:

1. Декларация о человеческом языке

x - количество итераций, которые прошли. n - количество итераций (вы можете использовать целое число вместо 5, 1-го блока, или вы можете использовать n для замены 5 для буквального n-го итерационного действия, блок 2) Наша цель - сделать что-то каждую x-ю итерацию и каждую 5-ю итерацию. Мы проводим 100 итераций.

1. Легко понятный код

Блок 1, минимальные переменные:

for x in 100:
    #what to do every time.
    if x % 5 == 0:
        #what to do every 5th time.

блок b, обобщение.

n = 5
for x in 100:
    #what to do every time.
    if x % n == 0:
        #what to do every 5th time.

Пожалуйста, дайте мне знать, если у вас есть какие-либо проблемы, потому что у меня не было времени проверить его после написания здесь.

3. Упражнения

  • Если вы сделали это правильно, посмотрите, можете ли вы использовать его с помощью функции turtle.Pen() и turtle.forward().
  • Посмотрите, можете ли вы использовать эту программу с помощью функции turtle.circle().
  • Просмотрите показания, чтобы попытаться улучшить свои программы.

О модуле и других основных операторах: https://docs.python.org/2/library/stdtypes.html http://www.tutorialspoint.com/python/python_basic_operators.htm

О черепахе: https://docs.python.org/2/library/turtle.html https://michael0x2a.com/blog/turtle-examples

Ответ 5

Я проведу некоторое тестирование, чтобы узнать, сколько времени вы потребляете в модуле. Вы можете использовать timeit. Если ваши результаты указывают на необходимость сокращения времени, другой подход, исключающий вычисление модуля:

for m in xrange(m_min, m_max):
    for n in xrange(n_min, n_max):
        #do_n_stuff
    print('Progress report...')

Ответ 6

Что-то вроде этого?

for n in xrange(1000000,11000000,1000000):
    for i in xrange(n-1000000,n):
        x = 10/2
    print 'Progress at '+str(i)

результат

Progress at 999999
Progress at 1999999
Progress at 2999999
Progress at 3999999
Progress at 4999999
Progress at 5999999
Progress at 6999999
Progress at 7999999
Progress at 8999999
Progress at 9999999

.

ИЗМЕНИТЬ

лучше:

for n in xrange(0,10000000,1000000):
    for i in xrange(n,n+1000000):
        x = 10/2
    print 'Progress at '+str(i)

И вдохновенный от pajton:

m = 1000000
for n in xrange(0,10*m,m):
    for i in xrange(n,n+m):
        x = 10/2
    print 'Progress at '+str(i+1)

Я предпочитаю это, чтобы найти более сразу читаемый, чем решение pajton. Он сохраняет отображение значения в зависимости от i

Ответ 7

Это достаточно быстро, чтобы я не беспокоился об этом.

Если вы действительно хотели ускорить его, вы могли бы сделать это, чтобы избежать модуля

if (n == 1000000):
    n = 0
    print('Progress report...')

Ответ 8

Это делает внутренний цикл худым, а m не нужно делиться на interval.

m = 10000000
interval = 1000000
i = 0
while i < m:
    checkpoint = min(m, i+interval)
    for j in xrange(i, checkpoint):
        #do something
    i = checkpoint
    print "progress"