использование печати в цикле замедляет цикл - PullRequest
0 голосов
/ 16 сентября 2018

Использование print в цикле замедляет цикл.Печать чего-то (я пробовал с Hello!) 100 раз займет ~ 2 секунды, без него это займет 0,0 секунды.Я точно зафиксировал время, используя модуль time.Вот цикл, который печатает в нем и показывает время, необходимое в конце:

import time

t = time.time()
for _ in range(100):
    print("Hello! ",end = "")

print("\n",time.time()-t)

Вывод:

Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! Hello! 
 1.9912450313568115

Вот еще один циклэто просто добавляет строку в переменную и это занимает 0,0 секунд .

import time

t = time.time()
output = ""
for _ in range(100):
    output += "Hello! "

print(time.time()-t)

Вывод:

0.0

Я пыталсядобавление дополнительных операций, но это все еще занимает 0.0 секунд.Пример:

import time

t = time.time()
output,num,count,abc = "",0,30,"H"
for _ in range(100):
    output += "Hello! "
    num += 10000
    count += 10000000
    abc += "Hello Guys!"

print(time.time()-t)




Почему print замедляет цикл и как я могу преодолеть эту проблему?

1 Ответ

0 голосов
/ 16 сентября 2018

print () замедлит ваш цикл.Это потому, что вы делаете системный вызов и операцию ввода-вывода каждый раз, когда вызываете print ().Системные вызовы потребляют много циклов ЦП и включают переключение контекста ЦП.Операции ввода-вывода на некоторое время заблокируют основной поток вашего процесса.

Таким образом, очевидным решением является либо исключить, либо уменьшить количество вызовов print ().

Если вам действительно нужен механизм длязнать текущий счетчик итераций цикла, тогда вы можете использовать многопоточность для достижения этой цели.Но все же, это может включать системные вызовы и переключение контекста потока.Но я предполагаю, что это будет все же быстрее, чем print ().

Хитрость заключается в том, чтобы выполнить цикл в фоновом потоке, пока вы печатаете прогресс в основном потоке.Таким образом, операция ввода-вывода в вызове print () не будет блокировать поток, который выполняет цикл.Чтобы еще больше оптимизировать его, вы можете распечатать прогресс только тогда, когда пользователь нажмет клавишу.

import threading

lock = threading.Lock()
count = 0

def your_method_with_a_loop():
    global count
    with open("f.txt","w") as f:
        for q in range(1000000):
            f.write(str(q)+"\n")
            #your_logic_here
            #....
            lock.acquire()
            count = count + 1
            lock.release()

#Run the loop in a background thread
t1 = threading.Thread(target=your_method_with_a_loop)
t1.start()

while t1.isAlive():
    print("Press enter to see current loop iteration count\n")
    #use raw_input() instead if your are using python 2.x.
    input() #Remove this line if you want to print progress continuously.
    lock.acquire() 
    current_count = count
    lock.release()
    print("Current loop iteration count is ",count,"\n")

Это решение улучшает ситуацию двумя способами

  1. IO операцияне выполняется в рабочем потоке.Да, использование блокировок подразумевает системный вызов.Но он все еще быстрее, чем блок ввода-вывода.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...