【问题标题】:How to print iterations per second?如何每秒打印迭代次数?
【发布时间】:2015-08-30 07:58:51
【问题描述】:

我有一个小的 Python 脚本,可以将 POST 请求发送到服务器并获得它们的响应。

它迭代了 10000 次,我设法在命令提示符下打印了当前进度:

code=current_requestnumber
print('{0}/{1}'.format(str(code),"10000"),end="\r")

在每个循环结束时。

因为这涉及与网络服务器的交互,所以我想在旁边显示当前的平均速度(每 2 秒更新一次)。

命令提示符底部的示例将如下所示:

(1245/10000),6.3 个请求/秒

我如何做到这一点?

【问题讨论】:

标签: python performance loops cmd progress


【解决方案1】:

这里使用进度条 2 是解决方案:

import time
import progressbar
widgets = [
    progressbar.Percentage(),
    ' ', progressbar.SimpleProgress(format=f'({progressbar.SimpleProgress.DEFAULT_FORMAT})'),
    ' ', progressbar.Bar(),
    ' ', progressbar.Timer(), ' | '
                              ' ', progressbar.ETA(), ' | ',
    ' ', progressbar.AdaptiveTransferSpeed(unit='it'),
]
bar = progressbar.ProgressBar(widgets=widgets)
for i in bar(range(100)):
    time.sleep(0.1)
    bar.update(i)
100% (100 of 100) |#####| Elapsed Time: 0:00:10 |  Time:  0:00:10 |    9.8 it/s

有关详细信息,请参阅讨论,感谢progressbar 2 的维护者拥有的精彩论坛:https://github.com/WoLpH/python-progressbar/discussions/253

【讨论】:

    【解决方案2】:

    使用python-progressbar2,您可以这样做:

    import time
    import progressbar
    
    
    widgets = [
        progressbar.Percentage(),
        progressbar.Bar(),
        ' ', progressbar.SimpleProgress(),
        ' ', progressbar.ETA(),
        ' ', progressbar.AdaptiveTransferSpeed(unit='it'),
    ]
    
    bar = progressbar.ProgressBar(widgets=widgets)
    for i in bar(range(100)):
        time.sleep(0.2)
        bar.update(i)
    

    这大致符合我的想法:)

     19%|########                               | 19 of 100 ETA:   0:00:17   4.9 it/s
    

    (免责声明:我是python-progressbar2的作者和维护者)

    【讨论】:

      【解决方案3】:

      这取决于您的请求是同步发送还是异步发送。

      对于同步发送,tqdm 库提供所需的统计信息。

      对于异步发送,您应该使用代码包装您的请求发送代码,以节省发送每个请求所需的时间,并作为回调更新一个保存统计信息并将其更新到屏幕的全局对象。 实现取决于您用于异步发送的库。

      【讨论】:

        【解决方案4】:

        您可以为此使用tqdm 库。一个简单的例子是

        from tqdm import tqdm
        for i in tqdm(range(1e20)):
            ##LOOP BODY
        

        这将打印当前迭代、迭代/秒、ETA 和一个漂亮的进度条

        例如

         21%|████████████████████  21/100 [01:45<04:27,  3.39s/it]
        
        

        【讨论】:

        • 你知道progressbar2的解决方案吗?
        【解决方案5】:

        您可以像这样获得每秒的平均事件总数:

        #!/usr/bin/env python3
        
        import time
        import datetime as dt
        
        start_time = dt.datetime.today().timestamp()
        i = 0
        while(True):
            time.sleep(0.1)
            time_diff = dt.datetime.today().timestamp() - start_time
            i += 1
            print(i / time_diff)
        

        在此示例中将打印大约 10。请注意,我使用了 datetimetimestamp 方法,该方法仅在 Python 3 中可用。

        现在,如果您想计算每秒的“当前”事件数,比如过去 10 个事件,您可以这样做:

        #!/usr/bin/env python3
        
        import time
        import datetime as dt
        
        last_time = dt.datetime.today().timestamp()
        diffs = []
        while(True):
            time.sleep(0.1)
        
            # Add new time diff to list
            new_time = dt.datetime.today().timestamp()
            diffs.append(new_time - last_time)
            last_time = new_time
        
            # Clip the list
            if len(diffs) > 10:
                diffs = diffs[-10:]
        
            print(len(diffs) / sum(diffs))
        

        在这里,我保留了最近 10 次迭代的持续时间列表,然后我可以使用它来获取每秒的平均事件数。

        【讨论】:

        • 当存在进度条时我为什么要这样做?
        • @CharlieParker 因为看起来 OP 正在尝试获取“每秒请求数”,这是一个经典的 Web 框架基准。不是进度条...
        【解决方案6】:

        计算完成的请求并除以程序已经执行的时间?

        time.time 将有助于获取时间。其余的只是将 current_requestnumber 除以自开始以来的秒数差... 这样你就可以得到长期平均值。如果您需要在速度变化时快速显示它会变得有点复杂,因为您需要计算最后 10 秒的请求数。 (一种方法是在上次重置后超过 10 秒后重置计数器)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-12-17
          • 1970-01-01
          • 2013-04-16
          • 1970-01-01
          • 1970-01-01
          • 2012-10-06
          • 2021-10-12
          • 1970-01-01
          相关资源
          最近更新 更多