在循环中使用打印会减慢循环速度 [英] using print in loop slows down the loop

查看:34
本文介绍了在循环中使用打印会减慢循环速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在循环中使用 print 会减慢循环速度.打印一些东西 (我用 Hello! 尝试过) 100 次需要大约 2 秒,没有它需要 0.0 秒.我使用模块 time 准确地捕获了时间.这是一个打印在其中并显示最后花费的时间的循环:

导入时间t = time.time()对于 _ 范围(100):print("你好!",end = "")打印("\n",time.time()-t)

输出:

<块引用>

你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!1.9912450313568115

<小时>

这是另一个将字符串添加到变量的循环,它需要 0.0 秒.

导入时间t = time.time()输出 = ""对于 _ 范围(100):输出 += "你好!"打印(时间.时间()-t)

输出:

<块引用>

0.0

<小时>

我尝试添加更多操作,但仍然需要 0.0 秒.示例:

导入时间t = time.time()output,num,count,abc = "",0,30,"H"对于 _ 范围(100):输出 += "你好!"数量 += 10000计数 += 10000000abc += "大家好!"打印(时间.时间()-t)




为什么 print 会减慢循环速度,我该如何解决这个问题?

解决方案

print() 会减慢循环速度.那是因为每次调用print() 时都会进行系统调用和IO 操作.系统调用会消耗大量 CPU 周期并涉及 CPU 上下文切换.IO 操作会阻塞你进程的主线程一段时间.

所以显而易见的解决方案是消除或减少 print() 调用的次数.

如果你真的需要一种机制来知道当前循环的迭代次数,那么你可以使用多线程来实现这一点.但是,它仍然可能涉及系统调用和线程上下文切换.但我想它仍然会比 print() 快.

诀窍是在主线程中打印进度时在后台线程中执行循环.这样调用 print() 的 IO 操作就不会阻塞运行循环的线程.为了进一步优化它,您可以仅在用户按下某个键时打印进度.

导入线程锁 = threading.Lock()计数 = 0def your_method_with_a_loop():全局计数with open("f.txt","w") as f:对于范围内的 q(1000000):f.write(str(q)+"\n")#your_logic_here#....锁定.获取()计数 = 计数 + 1锁.释放()#在后台线程中运行循环t1 = threading.Thread(target=your_method_with_a_loop)t1.start()而 t1.isAlive():print("按回车查看当前循环迭代次数\n")#use raw_input() 如果您使用的是 python 2.x.input() #如果要连续打印进度,请删除此行.锁定.获取()current_count = 计数锁.释放()print("当前循环迭代次数为",count,"\n")

这个解决方案通过两种方式改善了这种情况

  1. IO 操作不在工作线程上执行.是的,使用锁涉及系统调用.但它仍然比 IO 块快.

  2. 假设python解释器使用futex来实现锁,那么获取和释放锁的成本是非常慢的,因为与工作线程相比,主线程很少持有锁.

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?

解决方案

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.

这篇关于在循环中使用打印会减慢循环速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆