Nouman
Nouman

Reputation: 7313

using print in loop slows down the loop

Using print in a loop slows down the loop. Printing something (I tried with Hello!) 100 times take ~2 sec, without it, it takes 0.0 second. I accurately captured the time using module time. Here is a loop that prints in it and shows the time taken at the end:

import time

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

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

Output:

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

Here is another loop that just adds string to a variable and its taking 0.0 seconds.

import time

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

print(time.time()-t)

Output:

0.0

I tried adding more operations but it it still taking 0.0 seconds. Example:

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)




Why does print slow down the loop and how can I overcome this problem?

Upvotes: 3

Views: 3029

Answers (1)

Vishnuprasad R
Vishnuprasad R

Reputation: 1730

print() will slow down your loop. That is because you are making a system call and an IO operation each time you call print(). System calls consume a lot of CPU cycles and involves CPU context switch. IO operations will block the main thread of your process for sometime.

So the obvious solution is to either eliminate or reduce the number of print() calls.

If you really need a mechanism to know the current iteration count of loop, then you can use multi-threading to achieve this. But still, it may involve system calls and thread context switching. But I suppose it will be still faster than print().

The trick is to perform the loop in a background thread while you print the progress in main thread. This way the IO operation in calling print() wont block the thread that runs the loop. To optimize it even further, you can print the progress only when user press a key.

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")

This solution improves the situation by two ways

  1. IO operation is not performed on the worker thread. Yes using locks involves system call. But it is still faster than an IO block.

  2. Assuming that the python interpreter uses futex to implement locks, then the cost of aquiring and releasing the lock is very slow, since when compared to worker thread the main thread would rarely hold the lock.

Upvotes: 5

Related Questions