【问题标题】:How do you determine a processing time in Python?你如何确定 Python 中的处理时间?
【发布时间】:2010-11-30 17:04:12
【问题描述】:

我是 Python 新手,对日期/时间文档感到困惑。我想计算执行计算所需的时间。

在java中,我会写:

long timeBefore = System.currentTimeMillis();
doStuff();
long timeAfter = System.currentTimeMillis();
elapsed time = timeAfter - timeBefore;

我确信在 Python 中它更容易。有人可以帮忙吗?

【问题讨论】:

  • 具体来说,你在看什么Python代码?
  • 我不是在看 Python 代码,而是在准备写它。顺便说一句,我对你的 Building Skills in Python 这本书很感兴趣,我会去看看。

标签: python datetime


【解决方案1】:

python 中的等价物是:

>>> import time
>>> tic = time.clock()
>>> toc = time.clock()
>>> toc - tic

如果您正在尝试找到性能最佳的方法,那么您可能应该看看timeit

【讨论】:

  • 确实,prob clock 更适合这种测量。
  • 感谢您提供等价物。将来我必须研究timeit,但对于我目前的小练习来说,这就足够了。
  • 请注意,time.clock 并非在所有平台上都执行相同的操作。更值得注意的是,在 unix 上,它返回的是处理器时间,而不是时钟时间。
  • time.clock() 自 Python 3.3 起已弃用,自 Python 3.7 起打印警告。现在推荐的函数是time.process_time()time.perf_counter()。见docs.python.org/3/library/time.html#time.clock
【解决方案2】:

基于和更新一些早期响应(感谢:SilentGhost、nosklo、Ramkumar),一个简单的便携式计时器将使用timeitdefault_timer()

>>> import timeit
>>> tic=timeit.default_timer()
>>> # Do Stuff
>>> toc=timeit.default_timer()
>>> toc - tic #elapsed time in seconds

这将返回经过的挂钟(实际)时间,而不是 CPU 时间。正如timeit documentation 中所述,根据平台选择最精确的可用现实世界计时器。

此外,从 Python 3.3 开始,time.perf_counter 性能计数器提供了相同的功能。在 3.3+ 下 timeit.default_timer() 指的是这个新的计数器。

对于更精确/复杂的性能计算,timeit 包含更复杂的调用,用于自动计时小代码 sn-ps,包括在定义的一组重复上平均运行时间。

【讨论】:

    【解决方案3】:

    您可以实现两个tic()tac() 函数,其中tic() 捕获它被调用的时间,tac() 打印自调用tic() 以来的时间差。这是一个简短的实现:

    import time
    
    _start_time = time.time()
    
    def tic():
        global _start_time 
        _start_time = time.time()
    
    def tac():
        t_sec = round(time.time() - _start_time)
        (t_min, t_sec) = divmod(t_sec,60)
        (t_hour,t_min) = divmod(t_min,60) 
        print('Time passed: {}hour:{}min:{}sec'.format(t_hour,t_min,t_sec))
    

    现在在您的代码中,您可以将其用作:

    tic()
    do_some_stuff()
    tac()
    

    它会输出,例如:

    Time passed: 0hour:7min:26sec
    

    另见:

    【讨论】:

    • 不是tic/toc吗? :-)
    • 他可能是法国人:)
    【解决方案4】:

    对于 Python 3.3 及更高版本,time.process_time() 非常好:

    import time
    
    t = time.process_time()
    #do some stuff
    elapsed_time = time.process_time() - t
    

    【讨论】:

    • 请注意,这会忽略代码中的任何time.sleep() 时间延迟,我只是尝试用time.sleep() 对其进行测试一分钟,结果很困惑!例如。如果您想以精确的时间间隔重复该过程,例如网络抓取,可以测量 elapsed_time 然后添加适当的time.sleep()延迟
    • 说得太快了,其实我只是用selenium包打开网站登录,发送消息,可以看到selenium在文本框中填写消息需要20秒或更长时间,但得到0.125为从process_time() 获取 URL 到结束键入消息的时间之前经过的时间,不知道发生了什么,文档提到 time.sleep() 延迟被 process_time 忽略,但填充框肯定是正常的处理时间,发送几个 send_keys( ) 来自 selenium 的调用来执行此操作。
    • @WillCroxford 我遇到了与 process_time() 类似的情况。 time() 给出了我在函数执行之前所经历的等待的更准确数字。
    【解决方案5】:

    【讨论】:

      【解决方案6】:

      我还需要计算一些代码行的处理时间。所以我尝试了批准的答案,我收到了这个警告。

      DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead
      

      所以 python 将从Python 3.8 转换为remove time.clock()。您可以从问题#13270 中了解更多信息。此警告建议使用两个函数而不是 time.clock()。在文档中还详细提到了time.clock() 部分中的此警告。

      自 3.3 版起已弃用,将在 3.8 版中删除:此函数的行为取决于平台:根据您的要求使用 perf_counter() 或 process_time() 来获得明确定义的行为。

      让我们详细了解这两个函数。


      返回性能计数器的值(以秒为单位),即具有最高可用分辨率的时钟以测量短持续时间。它确实包括睡眠期间经过的时间,并且是系统范围的。返回值的参考点是未定义的,所以只有两次调用结果的差异才有效。

      3.3 版中的新功能。

      在 3.10 版中更改:在 Windows 上,该功能现在是系统范围的。

      所以如果你想要它为nanoseconds,你可以使用time.perf_counter_ns(),如果你的代码与time.sleep(secs)一致,它也将被计算在内。例如:-

      import time
      
      
      def func(x):
          time.sleep(5)
          return x * x
      
      
      lst = [1, 2, 3]
      tic = time.perf_counter()
      print([func(x) for x in lst])
      toc = time.perf_counter()
      print(toc - tic)
      
      # [1, 4, 9]
      # 15.0041916 --> output including 5 seconds sleep time
      

      返回当前进程的系统和用户 CPU 时间之和的值(以秒为单位)。它不包括睡眠期间经过的时间。根据定义,它是进程范围的。返回值的参考点是未定义的,所以只有两次调用结果的差异才有效。

      使用process_time_ns()避免float类型造成的精度损失。

      3.3 版中的新功能。

      因此,如果您希望它为nanoseconds,则可以使用time.process_time_ns(),如果您的代码与time.sleep(secs) 一致,则不会计算在内。例如:-

      import time
      
      
      def func(x):
          time.sleep(5)
          return x * x
      
      
      lst = [1, 2, 3]
      tic = time.process_time()
      print([func(x) for x in lst])
      toc = time.process_time()
      print(toc - tic)
      
      # [1, 4, 9]
      # 0.0 --> output excluding 5 seconds sleep time
      

      请注意time.perf_counter_ns()time.process_time_ns() 都想出Python 3.7

      【讨论】:

        【解决方案7】:
        python -m timeit -h
        

        【讨论】:

          【解决方案8】:

          有关如何确定处理时间的更多信息,以及几种方法的比较(一些方法已经在本文的答案中提到) - 具体来说,它们之间的区别:

          start = time.time()
          

          与现在已过时的 (as of 3.3, time.clock() is deprecated)

          start = time.clock()
          

          在此处查看有关 Stackoverflow 的另一篇文章:

          Python - time.clock() vs. time.time() - accuracy?

          如果没有别的,这会很好用:

          start = time.time()
          
          ... do something
          
          elapsed = (time.time() - start)
          

          【讨论】:

            【解决方案9】:

            如果您想要的只是代码中两点之间的时间(这似乎就是您想要的),我已经编写了 tic() toc() 函数 ala Matlab 的实现。基本用例是:

            tic()
            
            ''' some code that runs for an interesting amount of time '''
            
            toc()
            
            # OUTPUT:
            # Elapsed time is: 32.42123 seconds
            

            超级,非常易于使用,一种即发即弃的代码。它可以在 Github 的 Gist 上找到 https://gist.github.com/tyleha/5174230

            【讨论】:

            • time.time() 不是单调的,不能用于测量时间间隔
            • 有趣,你是对的。很高兴学到新东西!此外,感谢您花时间挖掘这个 3 年前的答案,通读我的 Gist,对我投反对票,但没有提供替代建议或解释为什么它是非单调的!对于那些希望真正改进代码和学习的人,我自己的一些研究建议你应该使用time.monotonic,它在 Python 3.3+(我现在使用)中可用。 time.time 不是单调的,因为它依赖于系统时间,可以在运行中修改
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-01
            • 2014-07-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多