打印进度更新时的效率,打印x vs如果x%y==0:打印x

2024-05-18 21:05:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在运行一个算法,使用Python逐行读取excel文档,并将这些行推送到SQL服务器。我想打印一些循环的进程。我可以想出两个非常简单的选择,我想知道哪个更轻,为什么。 方案A:

for x in xrange(1, sheet.nrows):
    print x
    cur.execute() # pushes to sql

方案B:

for x in xrange(1, sheet.nrows):
    if x % some_check_progress_value == 0:
        print x
    cur.execute() # pushes to sql

我有一种感觉,第二个会更有效,但只适用于更大规模的项目。有没有办法计算/确定这一点?你知道吗


Tags: toin文档算法forexecutesql方案
3条回答

我是tqdm, a Python progress bar的开发人员之一,它在提供尽可能多的自动化特性的同时,尽量提高效率。你知道吗

我们最大的性能损失确实是I/O:打印到控制台/文件/任何东西。你知道吗

但是如果你的循环很紧(超过100次迭代/秒),那么每次更新都打印是没有用的,你最好只打印1/10的更新,用户看不出有什么区别,而你的条会减少10倍的开销(更快)。你知道吗

为了解决这个问题,我们首先添加了一个mininterval参数,它只每隔x秒更新一次显示(默认情况下是0.1秒,人眼看不到比这个更快的东西)。类似于:

import time

def my_bar(iterator, mininterval=0.1)
counter = 0
last_print_t = 0
for item in iterator:
    if (time.time() - last_print_t) >= mininterval:
        last_print_t = time.time()
        print_your_bar_update(counter)
    counter += 1

这将主要解决您的问题,因为您的栏将始终有一个恒定的显示开销,这将越来越可以忽略,因为您有更大的迭代器。你知道吗

如果您想进一步优化,time.time()也是一个I/O操作,因此比简单的Python语句成本更高。为了避免这种情况,您希望通过引入另一个变量来最小化对time.time()的调用:miniters,这是您在检查时间之前要跳过的最小迭代次数:

import time

def my_bar(iterator, mininterval=0.1, miniters=10)
counter = 0
last_print_t = 0
last_print_counter = 0
for item in iterator:
    if (counter - last_print_counter) >= miniters:
        if (time.time() - last_print_t) >= mininterval:
            last_print_t = time.time()
            last_print_counter = counter
            print_your_bar_update(counter)
    counter += 1

您可以看到miniters与optionb模数解决方案类似,但随着时间的推移,它更适合作为一个附加层,因为时间更容易配置。你知道吗

有了这两个参数,您可以手动微调进度条,使其成为循环中最有效的。你知道吗

然而,miniters(或模数)很难在没有手动微调的情况下对每个人都起作用,您需要做出很好的假设和巧妙的技巧来自动进行微调。这是我们正在进行的主要工作之一。基本上,我们所做的就是计算miniters等于mininterval,这样时间检查就不再需要了。这个automagic设置在mininterval被触发后生效,类似于:

from __future__ import division
import time

def my_bar(iterator, mininterval=0.1, miniters=10, dynamic_miniters=True)
counter = 0
last_print_t = 0
last_print_counter = 0
for item in iterator:
    if (counter - last_print_counter) >= miniters:
        cur_time = time.time()
        if (cur_time - last_print_t) >= mininterval:
            if dynamic_miniters:
                # Simple rule of three
                delta_it = counter - last_print_counter
                delta_t = cur_time - last_print_t
                miniters = delta_it * mininterval / delta_t
            last_print_t = cur_time
            last_print_counter = counter
            print_your_bar_update(counter)
    counter += 1

自动计算miniters有多种方法,但通常需要更新它以匹配mininterval。你知道吗

如果您对挖掘更多内容感兴趣,可以检查dynamic_miniters内部参数maxintervaltqdm projectexperimental monitoring thread。你知道吗

我是新手,所以我不能评论。一个“答案”也许有点过分,但这是我目前所能做的。你知道吗

我最喜欢的是tqdm。它是微创的,无论是代码方面还是输出方面,都能完成任务。你知道吗

使用模数检查(计数器%N==0)几乎是免费的,如果您运行一个高频率的迭代(log a lot),这是一个很好的解决方案。 特别是如果您不需要为每个迭代打印,但希望在过程中得到一些反馈。你知道吗

相关问题 更多 >

    热门问题