You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化tqdm.set_postfix_str避免其拖慢程序运行速度?

问题描述

使用tqdm进度条工具追踪迭代过程的实时计算指标时,调用set_postfix_str方法更新进度条后缀会导致程序运行速度大幅下降,测试代码如下:

from tqdm import tqdm
import time
N = 10000

pbar = tqdm(range(N), total=N, desc="N")
start = time.time()
for i in pbar:
    pass
print("w/o set_postfix_str: {:.2f}".format(time.time() - start))

pbar = tqdm(range(N), total=N, desc="N")
start = time.time()
for i in pbar:
    pass
    pbar.set_postfix_str(s="{}".format(i))
print("w set_postfix_str: {:.2f}".format(time.time() - start))

运行输出:

N: 100%|██████████| 10000/10000 [00:00<00:00, 1239195.20it/s]
w/o set_postfix_str: 0.01
N: 100%|██████████| 10000/10000 [00:12<00:00, 774.67it/s, 9999]
w set_postfix_str: 12.91

已尝试设置tqdm的miniters参数,但未取得优化效果,需要提升set_postfix_str的运行速度。

原因说明

set_postfix_str方法默认携带refresh=True参数,每次调用都会强制立即触发终端输出刷新,完全绕过tqdm自带的miniters、mininterval刷新频率限制。终端IO操作本身开销很高,逐迭代触发刷新会产生大量无效IO,直接拖慢整体运行速度,这也是单独设置miniters不生效的核心原因。

优化方法
  • 给set_postfix_str传入refresh=False参数
    该配置下方法只会更新后缀存储的内容,不会立刻触发终端重绘,刷新动作交还给tqdm按照初始化时设置的miniters(每迭代多少次刷新一次)、mininterval(每多少秒最多刷新一次)规则自动执行,从根源减少无效IO。
    示例修改:
    # 初始化时可同时配置刷新间隔,比如每0.1秒最多刷新一次
    pbar = tqdm(range(N), total=N, desc="N", mininterval=0.1)
    start = time.time()
    for i in pbar:
        pass
        # 关闭强制刷新
        pbar.set_postfix_str(s="{}".format(i), refresh=False)
    
    该修改下运行耗时会和不调用后缀更新的版本基本持平,仅存在毫秒级差异。
  • 优先使用set_postfix方法传递指标
    如果是展示键值对形式的计算指标,直接用tqdm内置的set_postfix方法即可,不需要手动拼接字符串。该方法自带格式化优化,默认就不会强制逐次刷新,性能比手动拼字符串调用set_postfix_str更好,示例:
    pbar.set_postfix(iter=i, loss=current_loss, refresh=False)
    
  • 手动控制更新频率
    也可以自行加判断逻辑,每隔固定迭代次数、或者固定时间间隔才调用一次后缀更新方法,减少调用次数自然就能降低性能开销,比如每迭代100次才更新一次后缀。

内容的提问来源于stack exchange,提问作者biock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 17:54:25