代码之家  ›  专栏  ›  技术社区  ›  Nouman ProfHase85

在循环中使用打印会减慢循环速度

  •  0
  • Nouman ProfHase85  · 技术社区  · 6 年前

    使用 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)
    




    打印 放慢循环速度,我如何克服这个问题?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Patrick Artner    6 年前

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

    因此,显而易见的解决方案是消除或减少print()调用的数量。

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

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

    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. 假设python解释器使用 futex 为了实现锁,获取和释放锁的成本非常低,因为与工作线程相比,主线程很少持有锁。