【问题标题】:How to measure elapsed time in Python?如何在 Python 中测量经过的时间?
【发布时间】:2019-12-30 06:26:56
【问题描述】:

我想要的是在我的代码中的某个地方开始计算时间,然后获取经过的时间,以测量执行几个函数所花费的时间。我认为我使用错误的 timeit 模块,但文档只是让我感到困惑。

import timeit

start = timeit.timeit()
print("hello")
end = timeit.timeit()
print(end - start)

【问题讨论】:

标签: python performance measure timeit


【解决方案1】:

如果你只想测量两点之间经过的挂钟时间,你可以使用time.time()

import time

start = time.time()
print("hello")
end = time.time()
print(end - start)

这给出了以秒为单位的执行时间。

自 3.3 以来的另一个选项可能是使用 perf_counterprocess_time,具体取决于您的要求。在 3.3 之前建议使用time.clock(感谢Amber)。但是,它目前已被弃用:

在 Unix 上,以浮点数形式返回当前处理器时间 以秒表示。精度,实际上就是定义 “处理器时间”的含义,取决于 C 函数的含义 同名。

在 Windows 上,此函数返回自挂钟以来经过的秒数 首先调用这个函数,作为一个浮点数,基于 Win32 函数QueryPerformanceCounter()。分辨率通常为 优于一微秒。

3.3 版后已弃用:此函数的行为取决于 在平台上:改用perf_counter()process_time(), 根据您的要求,有一个明确定义的行为。

【讨论】:

  • 对于微秒,使用 datetime.time()
  • (对于性能测量,time.clock() 实际上是首选,因为如果系统时钟被弄乱,它不会受到干扰,但.time() 主要完成相同的目的。)跨度>
  • 我认为 python -mtimeit 更好,因为它运行的次数更多,并且它是作为在 python 中测量时间的原生方式而构建的
  • 有没有一种很好的方法可以将生成的执行时间(以秒为单位)转换为 HH:MM::SS 之类的时间?
  • @Danijel:print(timedelta(seconds=execution_time))。虽然这是一个单独的问题。
【解决方案2】:

使用time.time 来衡量执行情况可为您提供命令的总体执行时间,包括计算机上其他进程所花费的运行时间。是用户注意的时候,但是如果要比较不同的代码sn-ps/算法/函数/...

更多信息timeit

如果您想更深入地了解分析:

更新:去年我经常使用http://pythonhosted.org/line_profiler/,发现它很有帮助,建议使用它来代替 Python 的配置文件模块。

【讨论】:

    【解决方案3】:

    给定一个你想要计时的函数,

    test.py:

    def foo(): 
        # print "hello"   
        return "hello"
    

    使用timeit 最简单的方法是从命令行调用它:

    % python -mtimeit -s'import test' 'test.foo()'
    1000000 loops, best of 3: 0.254 usec per loop
    

    不要尝试使用time.timetime.clock(天真地)来比较函数的速度。 They can give misleading results.

    PS。不要将打印语句放在您希望计时的函数中;否则测量的时间将取决于speed of the terminal

    【讨论】:

      【解决方案4】:

      python cProfile 和 pstats 模块为测量某些函数中经过的时间提供了强大的支持,而无需在现有函数周围添加任何代码。

      例如,如果你有一个 python 脚本 timeFunctions.py:

      import time
      
      def hello():
          print "Hello :)"
          time.sleep(0.1)
      
      def thankyou():
          print "Thank you!"
          time.sleep(0.05)
      
      for idx in range(10):
          hello()
      
      for idx in range(100):
          thankyou()
      

      要运行分析器并为文件生成统计信息,您只需运行即可:

      python -m cProfile -o timeStats.profile timeFunctions.py
      

      这样做是使用 cProfile 模块来分析 timeFunctions.py 中的所有函数,并在 timeStats.profile 文件中收集统计信息。请注意,我们不必向现有模块 (timeFunctions.py) 添加任何代码,这可以通过任何模块完成。

      获得统计文件后,您可以按如下方式运行 pstats 模块:

      python -m pstats timeStats.profile
      

      这会运行交互式统计浏览器,它为您提供了很多不错的功能。对于您的特定用例,您只需检查函数的统计信息。在我们的示例中,检查这两个函数的统计数据向我们展示了以下内容:

      Welcome to the profile statistics browser.
      timeStats.profile% stats hello
      <timestamp>    timeStats.profile
      
               224 function calls in 6.014 seconds
      
         Random listing order was used
         List reduced from 6 to 1 due to restriction <'hello'>
      
         ncalls  tottime  percall  cumtime  percall filename:lineno(function)
             10    0.000    0.000    1.001    0.100 timeFunctions.py:3(hello)
      
      timeStats.profile% stats thankyou
      <timestamp>    timeStats.profile
      
               224 function calls in 6.014 seconds
      
         Random listing order was used
         List reduced from 6 to 1 due to restriction <'thankyou'>
      
         ncalls  tottime  percall  cumtime  percall filename:lineno(function)
            100    0.002    0.000    5.012    0.050 timeFunctions.py:7(thankyou)
      

      虚拟示例并没有做太多的事情,但可以让您了解可以做什么。这种方法最好的部分是我不必编辑任何现有代码来获取这些数字,并且显然有助于分析。

      【讨论】:

      • 这一切都很好,但是 AFAICT 这仍然测量 CPU 时间,而不是挂钟时间。
      • 其实有些混乱;看来 cProfile 默认情况下确实会查看挂钟时间。我赞成你的回答。
      • 仅供参考:如果您收到 python -m pstats timeStats.profile ValueError: bad marshal data (unknown type code),请检查您正在运行的 python 版本。当我运行python3 -m cProfile...python -m pstats 时,我得到了这个。我的错误,但让我一秒钟,所以,我想分享don't forget consistency。 =)
      【解决方案5】:

      仅限 Python 3:

      由于time.clock()is deprecated as of Python 3.3,您将希望使用time.perf_counter() 进行系统范围的计时,或使用time.process_time() 进行进程范围的计时,就像您过去使用time.clock() 的方式一样:

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

      新函数process_time 将不包括睡眠期间经过的时间。

      【讨论】:

      • Use timeit.default_timer 而不是 time.perf_counter。前者会选择合适的计时器来衡量针对你的平台和 Python 版本调整的时间性能。 process_time()包括睡眠期间的时间,因此不适合测量经过的时间。
      • 我正在使用 Pierre 建议的实现,数值是否以秒为单位?
      • 这个答案似乎离题了(嗯,这个问题不是很具体)。有两个“时间”测量:两点之间的挂钟时间,进程的cpu消耗。
      • @fjs timeit.default_timer 在 Python 中使用 time.perf_counter >=3.3 docs.python.org/3/library/timeit.html#timeit.default_timer
      • elapsed_time 返回 0.07812 例如。我该如何解释?秒是 1.000,所以我的脚本在 7,812 毫秒内运行?
      【解决方案6】:

      使用timeit.default_timer 而不是timeit.timeit。前者自动提供在您的平台和 Python 版本上可用的最佳时钟:

      from timeit import default_timer as timer
      
      start = timer()
      # ...
      end = timer()
      print(end - start) # Time in seconds, e.g. 5.38091952400282
      

      timeit.default_timer 分配给 time.time() 或 time.clock() 取决于操作系统。在 Python 3.3+ 上,default_timer 在所有平台上都是 time.perf_counter()。见Python - time.clock() vs. time.time() - accuracy?

      另见:

      【讨论】:

      • 优秀的答案 - 使用 timeit 将产生更准确的结果,因为它会自动考虑垃圾收集和操作系统差异等问题
      • 这给出的时间是毫秒还是秒?
      • @KhushbooTiwari 以秒为单位。
      • 我觉得官方文档中的这个注释需要加上default_timer() measurations can be affected by other programs running on the same machine, so the best thing to do when accurate timing is necessary is to repeat the timing a few times and use the best time. The -r option is good for this; the default of 3 repetitions is probably enough in most cases. On Unix, you can use time.clock() to measure CPU time.
      • @KGS:性能测量非常棘手(很容易误导自己)。这里还有许多其他相关的评论。按照答案中的链接。您可能还对提供相同接口的perf module (nonexistent at the time of the answer) 感兴趣,但它有时与timeit 模块决定如何测量时间性能不同。
      【解决方案7】:

      (仅限 Ipython)您可以使用 %timeit 来测量平均处理时间:

      def foo():
          print "hello"
      

      然后:

      %timeit foo()
      

      结果是这样的:

      10000 loops, best of 3: 27 µs per loop
      

      【讨论】:

      • 值得一提的是,可以将标志传递给 %timeit,例如 -n 指定代码应该重复多少次。
      【解决方案8】:

      使用上下文管理器执行此操作很有趣,它会在进入 with 块时自动记住开始时间,然后在块退出时冻结结束时间。通过一些小技巧,您甚至可以从同一个上下文管理器函数中获得块内运行的经过时间计数。

      核心库没有这个(但可能应该有)。到位后,您可以执行以下操作:

      with elapsed_timer() as elapsed:
          # some lengthy code
          print( "midpoint at %.2f seconds" % elapsed() )  # time so far
          # other lengthy code
      
      print( "all done at %.2f seconds" % elapsed() )
      

      这里有足够的contextmanager 代码:

      from contextlib import contextmanager
      from timeit import default_timer
      
      @contextmanager
      def elapsed_timer():
          start = default_timer()
          elapser = lambda: default_timer() - start
          yield lambda: elapser()
          end = default_timer()
          elapser = lambda: end-start
      

      还有一些可运行的演示代码:

      import time
      
      with elapsed_timer() as elapsed:
          time.sleep(1)
          print(elapsed())
          time.sleep(2)
          print(elapsed())
          time.sleep(3)
      

      请注意,通过此函数的设计,elapsed() 的返回值在块退出时被冻结,并且进一步调用返回相同的持续时间(在这个玩具示例中约为 6 秒)。

      【讨论】:

      【解决方案9】:

      我为此做了一个库,如果你想测量一个函数,你可以这样做

      
      from pythonbenchmark import compare, measure
      import time
      
      a,b,c,d,e = 10,10,10,10,10
      something = [a,b,c,d,e]
      
      @measure
      def myFunction(something):
          time.sleep(0.4)
      
      @measure
      def myOptimizedFunction(something):
          time.sleep(0.2)
      
      myFunction(input)
      myOptimizedFunction(input)
      

      https://github.com/Karlheinzniebuhr/pythonbenchmark

      【讨论】:

        【解决方案10】:

        在 python3 上:

        from time import sleep, perf_counter as pc
        t0 = pc()
        sleep(1)
        print(pc()-t0)
        

        优雅而简短。

        【讨论】:

        • 这是什么?女士?
        • @KIC 只需几秒钟。
        【解决方案11】:

        这是一个返回“hh:mm:ss”字符串的小定时器类:

        class Timer:
          def __init__(self):
            self.start = time.time()
        
          def restart(self):
            self.start = time.time()
        
          def get_time_hhmmss(self):
            end = time.time()
            m, s = divmod(end - self.start, 60)
            h, m = divmod(m, 60)
            time_str = "%02d:%02d:%02d" % (h, m, s)
            return time_str
        

        用法:

        # Start timer
        my_timer = Timer()
        
        # ... do something
        
        # Get time string:
        time_hhmmss = my_timer.get_time_hhmmss()
        print("Time elapsed: %s" % time_hhmmss )
        
        # ... use the timer again
        my_timer.restart()
        
        # ... do something
        
        # Get time:
        time_hhmmss = my_timer.get_time_hhmmss()
        
        # ... etc
        

        【讨论】:

        【解决方案12】:

        我们还可以将时间转换为人类可读的时间。

        import time, datetime
        
        start = time.clock()
        
        def num_multi1(max):
            result = 0
            for num in range(0, 1000):
                if (num % 3 == 0 or num % 5 == 0):
                    result += num
        
            print "Sum is %d " % result
        
        num_multi1(1000)
        
        end = time.clock()
        value = end - start
        timestamp = datetime.datetime.fromtimestamp(value)
        print timestamp.strftime('%Y-%m-%d %H:%M:%S')
        

        【讨论】:

          【解决方案13】:

          另一种使用timeit的方法:

          from timeit import timeit
          
          def func():
              return 1 + 1
          
          time = timeit(func, number=1)
          print(time)
          

          【讨论】:

            【解决方案14】:

            这是另一个用于计时代码的上下文管理器 -

            用法:

            from benchmark import benchmark
            
            with benchmark("Test 1+1"):
                1+1
            =>
            Test 1+1 : 1.41e-06 seconds
            

            或者,如果您需要时间值

            with benchmark("Test 1+1") as b:
                1+1
            print(b.time)
            =>
            Test 1+1 : 7.05e-07 seconds
            7.05233786763e-07
            

            benchmark.py

            from timeit import default_timer as timer
            
            class benchmark(object):
            
                def __init__(self, msg, fmt="%0.3g"):
                    self.msg = msg
                    self.fmt = fmt
            
                def __enter__(self):
                    self.start = timer()
                    return self
            
                def __exit__(self, *args):
                    t = timer() - self.start
                    print(("%s : " + self.fmt + " seconds") % (self.msg, t))
                    self.time = t
            

            改编自http://dabeaz.blogspot.fr/2010/02/context-manager-for-timing-benchmarks.html

            【讨论】:

              【解决方案15】:

              你可以使用timeit。

              这是一个关于如何使用 Python REPL 测试带参数的 naive_func 的示例:

              >>> import timeit                                                                                         
              
              >>> def naive_func(x):                                                                                    
              ...     a = 0                                                                                             
              ...     for i in range(a):                                                                                
              ...         a += i                                                                                        
              ...     return a                                                                                          
              
              >>> def wrapper(func, *args, **kwargs):                                                                   
              ...     def wrapper():                                                                                    
              ...         return func(*args, **kwargs)                                                                  
              ...     return wrapper                                                                                    
              
              >>> wrapped = wrapper(naive_func, 1_000)                                                                  
              
              >>> timeit.timeit(wrapped, number=1_000_000)                                                              
              0.4458435332577161  
              

              如果函数没有任何参数,则不需要包装函数。

              【讨论】:

              • lambda 会更简洁:print(timeit.timeit(lambda: naive_func(1_000), number=1_000_000))
              【解决方案16】:

              使用分析器模块。它提供了非常详细的资料。

              import profile
              profile.run('main()')
              

              它输出类似:

                        5 function calls in 0.047 seconds
              
                 Ordered by: standard name
              
                 ncalls  tottime  percall  cumtime  percall filename:lineno(function)
                      1    0.000    0.000    0.000    0.000 :0(exec)
                      1    0.047    0.047    0.047    0.047 :0(setprofile)
                      1    0.000    0.000    0.000    0.000 <string>:1(<module>)
                      0    0.000             0.000          profile:0(profiler)
                      1    0.000    0.000    0.047    0.047 profile:0(main())
                      1    0.000    0.000    0.000    0.000 two_sum.py:2(twoSum)
              

              我发现它非常有用。

              【讨论】:

              • 什么是main()?如果你能提供一个简单的代码示例会更有用。
              【解决方案17】:

              我更喜欢这个。 timeit doc 太混乱了。

              from datetime import datetime 
              
              start_time = datetime.now() 
              
              # INSERT YOUR CODE 
              
              time_elapsed = datetime.now() - start_time 
              
              print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))
              

              请注意,这里没有任何格式,我只是在打印输出中写了hh:mm:ss,以便可以解释time_elapsed

              【讨论】:

              • 有人告诉我 timeit 计算 CPU 时间, datetime 是否也考虑了 CPU 使用时间?这些是一样的吗?
              • 以这种方式测量经过的时间是有风险的,因为 datetime.now() 可能由于网络时间同步、夏令时切换或用户摆弄时钟等原因在两个调用之间发生变化。
              • 来自 Shital Shah 的回答:“首先,如果您在 timeit 和 time.time 之间进行辩论,timeit 有两个优点:timeit 选择您的操作系统和 Python 版本上可用的最佳计时器。timeit 禁用垃圾收集,但是,这不是您可能想要也可能不想要的东西。”
              【解决方案18】:

              一种超级稍后的响应,但也许它对某人有用。这是一种我认为非常干净的方法。

              import time
              
              def timed(fun, *args):
                  s = time.time()
                  r = fun(*args)
                  print('{} execution took {} seconds.'.format(fun.__name__, time.time()-s))
                  return(r)
              
              timed(print, "Hello")
              

              请记住,“print”是 Python 3 中的一个函数,而不是 Python 2.7 中的一个函数。但是,它适用于任何其他功能。干杯!

              【讨论】:

              • 如何打印非常小的次数?我总是得到 0.0 秒
              • 你可以把它变成装饰器;这对我来说看起来更好。
              【解决方案19】:

              这是我在阅读了这里的许多好的答案以及其他几篇文章后的发现。

              首先,如果您在timeittime.time 之间争论,timeit 有两个优点:

              1. timeit 选择您的操作系统和 Python 版本上可用的最佳计时器。
              2. timeit 禁用垃圾收集,但是,这不是您可能想要也可能不想要的东西。

              现在的问题是timeit 使用起来并不简单,因为它需要设置,而且当你有一堆导入时事情会变得很糟糕。理想情况下,您只需要一个装饰器或使用with 块并测量时间。不幸的是,没有任何内置可用的功能,因此您有两种选择:

              选项 1:使用 timebudget 库

              timebudget 是一个多功能且非常简单的库,您只需在 pip 安装后的一行代码中即可使用它。

              @timebudget  # Record how long this function takes
              def my_method():
                  # my code
              

              选项 2:使用我的小模块

              我在名为timing.py 的小计时实用程序模块下创建了。只需将此文件放入您的项目并开始使用它。唯一的外部依赖是runstats,它又很小。

              现在你可以通过在它前面放置一个装饰器来为任何函数计时:

              import timing
              
              @timing.MeasureTime
              def MyBigFunc():
                  #do something time consuming
                  for i in range(10000):
                      print(i)
              
              timing.print_all_timings()
              

              如果您想对部分代码进行计时,只需将其放入 with 块中即可:

              import timing
              
              #somewhere in my code
              
              with timing.MeasureBlockTime("MyBlock"):
                  #do something time consuming
                  for i in range(10000):
                      print(i)
              
              # rest of my code
              
              timing.print_all_timings()
              

              优点:

              有几个半背版本浮动,所以我想指出几个亮点:

              1. 出于前面所述的原因,使用 timeit 中的计时器而不是 time.time。
              2. 如果需要,您可以在计时期间禁用 GC。
              3. 装饰器接受带有命名或未命名参数的函数。
              4. 能够在块定时中禁用打印(使用with timing.MeasureBlockTime() as t,然后使用t.elapsed)。
              5. 能够保持 gc 为块计时启用。

              【讨论】:

              • 关于“能够在块定时中禁用打印(使用with utils.MeasureBlockTime() as t,然后使用t.elapsed)。”:这不起作用,因为tNone。我认为__enter__需要返回self,并且要禁用打印,我们必须将其构造为utils.MeasureBlockTime(no_print=True)
              • @mic - 感谢您指出这一点。我已经用这个和其他几个增强功能更新了答案。
              【解决方案20】:

              除了 ipython 中的%timeit 之外,您还可以使用 %%timeit 进行多行代码 sn-ps:

              In [1]: %%timeit
                 ...: complex_func()
                 ...: 2 + 2 == 5
                 ...:
                 ...:
              
              1 s ± 1.93 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
              

              同样可以在jupyter notebook中使用,只需将magic %%timeit放在cell开头即可。

              【讨论】:

                【解决方案21】:

                测量时间以秒为单位:

                from timeit import default_timer as timer
                from datetime import timedelta
                
                start = timer()
                
                # ....
                # (your code runs here)
                # ...
                
                end = timer()
                print(timedelta(seconds=end-start))
                

                输出

                0:00:01.946339
                

                【讨论】:

                • 这是最简洁的答案,输出最干净。
                【解决方案22】:

                要以递归方式深入了解每个函数调用,请执行以下操作:

                %load_ext snakeviz
                %%snakeviz
                

                它只需要 Jupyter 笔记本 中的那 2 行代码,并生成一个漂亮的交互式图表。例如:

                这里是代码。同样,以% 开头的两行代码是使用snakeviz 所需的唯一额外代码行:

                # !pip install snakeviz
                %load_ext snakeviz
                import glob
                import hashlib
                
                %%snakeviz
                
                files = glob.glob('*.txt')
                def print_files_hashed(files):
                    for file in files:
                        with open(file) as f:
                            print(hashlib.md5(f.read().encode('utf-8')).hexdigest())
                print_files_hashed(files)
                

                似乎也可以在笔记本之外运行snakeviz。有关snakeviz website 的更多信息。

                【讨论】:

                  【解决方案23】:

                  我喜欢它简单(python 3):

                  from timeit import timeit
                  
                  timeit(lambda: print("hello"))
                  

                  单次执行的输出为 微秒

                  2.430883963010274
                  

                  说明: timeit 默认执行匿名函数100万次,结果以为单位。因此,1 次执行 的结果是相同的,但平均以 微秒 为单位。


                  对于 操作,请添加较少的 次迭代,否则您可能会一直等待:

                  import time
                  
                  timeit(lambda: time.sleep(1.5), number=1)
                  

                  次迭代的输出总是以为单位:

                  1.5015795179999714
                  

                  【讨论】:

                  • 输出是什么意思? timeit 会写入标准输出吗?
                  • 没有。我的意思是返回值。
                  【解决方案24】:

                  这是另一种方法:

                  >> from pytictoc import TicToc
                  >> t = TicToc() # create TicToc instance
                  >> t.tic() # Start timer
                  >> # do something
                  >> t.toc() # Print elapsed time
                  Elapsed time is 2.612231 seconds.
                  

                  与传统方式比较:

                  >> from time import time
                  >> t1 = time()
                  >> # do something
                  >> t2 = time()
                  >> elapsed = t2 - t1
                  >> print('Elapsed time is %f seconds.' % elapsed)
                  Elapsed time is 2.612231 seconds.
                  

                  安装:

                  pip install pytictoc
                  

                  有关详细信息,请参阅PyPi page

                  【讨论】:

                  • 最好解释一下使用这个库相对于其他方法的优势。
                  • 嵌套功能实际上被破坏了。我打开了一个问题,描述了代码中的问题在哪里,但回购协议一年内没有维护,所以我不希望有任何变化。
                  • 我发现嵌套有点混乱。如果我遇到埋在代码中的t.tic(),那么开发人员应该在脑海中列出我应该期待的系列中的哪个位置。您是否发现自己设置了巢穴或只是多个 tictocs?
                  • @PetarMI:仅供参考,我刚刚用ttictoc 解决了这个问题。我以前很乱,但现在应该好了。
                  • @hlg 如果我没记错的话,MATLAB 使用名称与时间类似的函数。所以我想优点是相似之处,对于那些在 MATLAB 中喜欢这个但改用 Python 的人来说。
                  【解决方案25】:

                  这种独特的基于类的方法提供了可打印的字符串表示、可自定义的舍入以及以字符串或浮点数形式方便地访问经过的时间。它是使用 Python 3.7 开发的。

                  import datetime
                  import timeit
                  
                  
                  class Timer:
                      """Measure time used."""
                      # Ref: https://stackoverflow.com/a/57931660/
                  
                      def __init__(self, round_ndigits: int = 0):
                          self._round_ndigits = round_ndigits
                          self._start_time = timeit.default_timer()
                  
                      def __call__(self) -> float:
                          return timeit.default_timer() - self._start_time
                  
                      def __str__(self) -> str:
                          return str(datetime.timedelta(seconds=round(self(), self._round_ndigits)))
                  

                  用法:

                  # Setup timer
                  >>> timer = Timer()
                  
                  # Access as a string
                  >>> print(f'Time elapsed is {timer}.')
                  Time elapsed is 0:00:03.
                  >>> print(f'Time elapsed is {timer}.')
                  Time elapsed is 0:00:04.
                  
                  # Access as a float
                  >>> timer()
                  6.841332235
                  >>> timer()
                  7.970274425
                  

                  【讨论】:

                  • 这是简单而优秀的——易于编码;我很惊讶 (a) 这种功能在任何现有的 Python 分析器中都不存在;并且 (b) 这个答案,包括一个可以复制和粘贴的简单类,在几年前并没有被提供给这个问题,并且获得了更多的支持。
                  【解决方案26】:
                  import time
                  
                  def getElapsedTime(startTime, units):
                      elapsedInSeconds = time.time() - startTime
                      if units == 'sec':
                          return elapsedInSeconds
                      if units == 'min':
                          return elapsedInSeconds/60
                      if units == 'hour':
                          return elapsedInSeconds/(60*60)
                  

                  【讨论】:

                  • 不要这样做,因为time.time() 不一定会均匀递增。如果有夏令时调整或其他什么,您可以获得负持续时间。将time.time() 替换为time.monotonic()
                  【解决方案27】:

                  timeit 模块适用于为一小段 Python 代码计时。它至少可以以三种形式使用:

                  1- 作为命令行模块

                  python2 -m timeit 'for i in xrange(10): oct(i)' 
                  

                  2- 对于短代码,将其作为参数传递。

                  import timeit
                  timeit.Timer('for i in xrange(10): oct(i)').timeit()
                  

                  3- 更长的代码为:

                  import timeit
                  code_to_test = """
                  a = range(100000)
                  b = []
                  for i in a:
                      b.append(i*2)
                  """
                  elapsed_time = timeit.timeit(code_to_test, number=100)/100
                  print(elapsed_time)
                  

                  【讨论】:

                    【解决方案28】:

                    时间也可以通过 %timeit 魔术函数来测量,如下所示:

                    %timeit -t -n 1 print("hello")
                    

                    n 1 仅用于运行功能 1 次。

                    【讨论】:

                      【解决方案29】:

                      测量小代码sn-ps的执行时间。

                      时间单位以秒为单位的浮点数

                      import timeit
                      t = timeit.Timer('li = list(map(lambda x:x*2,[1,2,3,4,5]))')
                      t.timeit()
                      t.repeat()
                      >[1.2934070999999676, 1.3335035000000062, 1.422568500000125]
                      

                      repeat() 方法方便多次调用 timeit() 并返回结果列表。

                      repeat(repeat=3)¶
                      

                      有了这个列表,我们可以取所有时间的平均值。

                      默认情况下,timeit() 在计时期间会暂时关闭垃圾回收。 time.Timer() 解决了这个问题。

                      优点:

                      timeit.Timer() 使独立计时更具可比性。 gc 可能是被测函数性能的重要组成部分。如果是这样,gc(garbage collector) 可以作为设置字符串中的第一条语句重新启用。例如:

                      timeit.Timer('li = list(map(lambda x:x*2,[1,2,3,4,5]))',setup='gc.enable()')
                      

                      来源Python Docs

                      【讨论】:

                        【解决方案30】:

                        如果您希望能够方便地对函数进行计时,可以使用简单的装饰器:

                        def timing_decorator(func):
                            def wrapper(*args, **kwargs):
                                start = time.time()
                                original_return_val = func(*args, **kwargs)
                                end = time.time()
                                print("time elapsed in ", func.__name__, ": ", end - start, sep='')
                                return original_return_val
                        
                            return wrapper
                        

                        你可以在你想要计时的函数上使用它:

                        @timing_decorator
                        def function_to_time():
                            time.sleep(1)
                        

                        然后,任何时候你调用function_to_time,它都会打印出花费了多长时间以及正在计时的函数的名称。

                        【讨论】:

                        • 有没有 Python2.x 的方式可以做到这一点,而不必从 __future__ 导入 print_function?我尝试使用join,但我对它的理解不够好,无法让它发挥作用。
                        • 更新。我想通了并使用了这个:print(''.join(["time elapsed in ",(func.__name__),": ",str(end - start)]))
                        猜你喜欢
                        • 2011-11-17
                        • 1970-01-01
                        • 2023-03-26
                        • 1970-01-01
                        • 2014-09-05
                        • 1970-01-01
                        相关资源
                        最近更新 更多