【问题标题】:Python speed testing - Time Difference - millisecondsPython 速度测试 - 时差 - 毫秒
【发布时间】:2022-09-13 19:37:45
【问题描述】:

为了加速测试一段代码,在 Python 中比较 2 次的正确方法是什么?我试着阅读 API 文档。我不确定我是否理解 timedelta 的事情。

到目前为止我有这段代码:

from datetime import datetime

tstart = datetime.now()
print t1

# code to speed test

tend = datetime.now()
print t2
# what am I missing?
# I'd like to print the time diff here

【问题讨论】:

  • 为什么不打印 t2-t1?是什么阻止了你做减法?
  • 猜猜,我有过“这不可能那么容易”的时刻。

标签: python datetime time time-measurement


【解决方案1】:

datetime.timedelta 只是两个日期时间之间的差异......所以它就像一段时间,以天/秒/微秒为单位

>>> import datetime
>>> a = datetime.datetime.now()
>>> b = datetime.datetime.now()
>>> c = b - a

>>> c
datetime.timedelta(0, 4, 316543)
>>> c.days
0
>>> c.seconds
4
>>> c.microseconds
316543

请注意,c.microseconds 仅返回 timedelta 的微秒部分!出于计时目的,始终使用c.total_seconds()

您可以使用 datetime.timedelta 进行各种数学运算,例如:

>>> c / 10
datetime.timedelta(0, 0, 431654)

不过,查看 CPU 时间而不是挂钟时间可能更有用……尽管这取决于操作系统……在类 Unix 系统下,请查看“time”命令。

【讨论】:

  • 在这种情况下,任何有兴趣获得总分钟数的人都可以使用int(c.total_seconds() / 60)
  • page for the timeit module 说该模块“避免了许多测量执行时间的常见陷阱”。这种方法(使用 datetime.now)是否存在这些陷阱?
  • @kuzzooroo 是的,是的!最好用 timeit 代替这个方法!例如,我在一个大型 Python 项目中进行了测试,使用此方法进行测量时,运行时间预计为 0.25 秒。实际上,根据 timeit,该函数的运行时间实际上是 30 秒!
  • 这不适用于准确计时,因为日期时间不是单调时钟
  • 如果您的 Python 程序通过 CPython 调用 C++ 代码,这似乎测量了错误的时间。
【解决方案2】:

从 Python 2.7 开始,就有了 timedelta.total_seconds() 方法。因此,要获得经过的毫秒数:

>>> import datetime
>>> a = datetime.datetime.now()
>>> b = datetime.datetime.now()
>>> delta = b - a
>>> print delta
0:00:05.077263
>>> int(delta.total_seconds() * 1000) # milliseconds
5077

【讨论】:

  • 如何以毫秒为单位准确显示?
  • @Buffalo - 这是准确的
【解决方案3】:

您可能想改用 the timeit module

【讨论】:

    【解决方案4】:

    我知道这已经晚了,但我真的很喜欢使用:

    import time
    start = time.time()
    
    ##### your timed code here ... #####
    
    print "Process time: " + (time.time() - start)
    

    time.time() 给你自纪元以来的秒数。因为这是以秒为单位的标准化时间,所以您可以简单地从结束时间减去开始时间以获得处理时间(以秒为单位)。 time.clock() 非常适合基准测试,但如果您想知道您的过程花费了多长时间,我发现它有点没用。例如,说“我的进程需要 10 秒”比说“我的进程需要 10 个处理器时钟单位”要直观得多

    >>> start = time.time(); sum([each**8.3 for each in range(1,100000)]) ; print (time.time() - start)
    3.4001404476250935e+45
    0.0637760162354
    >>> start = time.clock(); sum([each**8.3 for each in range(1,100000)]) ; print (time.clock() - start)
    3.4001404476250935e+45
    0.05
    

    在上面的第一个示例中,time.clock() 的时间为 0.05,而 time.time() 的时间为 0.06377

    >>> start = time.clock(); time.sleep(1) ; print "process time: " + (time.clock() - start)
    process time: 0.0
    >>> start = time.time(); time.sleep(1) ; print "process time: " + (time.time() - start)
    process time: 1.00111794472
    

    在第二个例子中,处理器时间以某种方式显示为“0”,即使进程休眠了一秒钟。 time.time() 正确显示了 1 秒多一点。

    【讨论】:

      【解决方案5】:

      您还可以使用:

      import time
      
      start = time.clock()
      do_something()
      end = time.clock()
      print "%.2gs" % (end-start)
      

      或者您可以使用python profilers

      【讨论】:

      • 使用start = time.clock() 时,它会打印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
      【解决方案6】:

      以下代码应显示时间增量...

      from datetime import datetime
      
      tstart = datetime.now()
      
      # code to speed test
      
      tend = datetime.now()
      print tend - tstart
      

      【讨论】:

        【解决方案7】:

        您可以简单地打印差异:

        print tend - tstart
        

        【讨论】:

          【解决方案8】:

          我不是 Python 程序员,但 I do know how to use Google 是我发现的:您使用“-”运算符。要完成您的代码:

          from datetime import datetime
          
          tstart = datetime.now()
          
          # code to speed test
          
          tend = datetime.now()
          print tend - tstart
          

          此外,看起来您可以使用 strftime() 函数来格式化时间跨度计算以呈现时间,但会让您开心。

          【讨论】:

            【解决方案9】:

            您可能需要查看 profile 模块。你会更好地了解你的减速在哪里,你的大部分工作将完全自动化。

            【讨论】:

            • 好主意!谢谢。
            【解决方案10】:

            Arrow:更好的 Python 日期和时间

            import arrow
            start_time = arrow.utcnow()
            end_time = arrow.utcnow()
            (end_time - start_time).total_seconds()  # senconds
            (end_time - start_time).total_seconds() * 1000  # milliseconds
            

            【讨论】:

              【解决方案11】:

              time.time() / datetime 适合快速使用,但并不总是 100% 精确。出于这个原因,我喜欢使用 std lib profilers(尤其是 hotshot)之一来找出什么是什么。

              【讨论】:

                【解决方案12】:

                这是一个模仿 Matlab 的/Octave 的tictoc函数的自定义函数。

                使用示例:

                time_var = time_me(); # get a variable with the current timestamp
                
                ... run operation ...
                
                time_me(time_var); # print the time difference (e.g. '5 seconds 821.12314 ms')
                

                功能 :

                def time_me(*arg):
                    if len(arg) != 0: 
                        elapsedTime = time.time() - arg[0];
                        #print(elapsedTime);
                        hours = math.floor(elapsedTime / (60*60))
                        elapsedTime = elapsedTime - hours * (60*60);
                        minutes = math.floor(elapsedTime / 60)
                        elapsedTime = elapsedTime - minutes * (60);
                        seconds = math.floor(elapsedTime);
                        elapsedTime = elapsedTime - seconds;
                        ms = elapsedTime * 1000;
                        if(hours != 0):
                            print ("%d hours %d minutes %d seconds" % (hours, minutes, seconds)) 
                        elif(minutes != 0):
                            print ("%d minutes %d seconds" % (minutes, seconds))
                        else :
                            print ("%d seconds %f ms" % (seconds, ms))
                    else:
                        #print ('does not exist. here you go.');
                        return time.time()
                

                【讨论】:

                • 追溯(最近调用最后):文件“redis-get-response.py”,第 22 行,在 <module> time_var = time_me(); # 获取具有当前时间戳的变量 文件“redis-get-response.py”,第 20 行,在 time_me 中 return time.time() NameError: name 'time' is not defined
                【解决方案13】:

                您需要改用 time.time(),它输出高精度的 unix 时间。

                使用此代码:

                from time import time
                
                tstart = time()
                doSomething()
                tend = time()
                difference = tend - tstart
                print("The doSomething function took {} seconds to execute".format(difference))
                

                【讨论】:

                  【解决方案14】:

                  您可以像这样使用 timeit 来测试名为 module.py 的脚本

                  $ python -mtimeit -s 'import module'
                  

                  【讨论】:

                    【解决方案15】:
                    start = datetime.now() 
                    
                    #code for which response time need to be measured.
                    
                    end = datetime.now()
                    dif = end - start
                    dif_micro = dif.microseconds # time in microseconds
                    dif_millis = dif.microseconds / 1000 # time in millisseconds
                    

                    【讨论】:

                    • 虽然此代码可能会提供问题的解决方案,但最好添加有关其工作原因/工作方式的上下文。这可以帮助未来的用户学习并最终将这些知识应用到他们自己的代码中。当解释代码时,您也可能会从用户那里得到积极的反馈/赞成票。
                    【解决方案16】:

                    如果有人需要这样的东西来分析日志条目之间的延迟,例如......等等。

                    def get_time_diff_between_timestruct_tuples(timestruct_tuples):
                        """
                        expecting input like:
                        [(0, datetime.datetime(2021, 10, 27, 16, 6, 8, 590892)),
                        (1, datetime.datetime(2021, 10, 27, 16, 6, 8, 591833)),
                        (2, datetime.datetime(2021, 10, 27, 16, 6, 9, 434053)),
                        (3, datetime.datetime(2021, 10, 27, 16, 6, 9, 878021)), ...]
                        
                        output like:
                        [0.941, 0.84222, 0.443968, ...]
                        """
                        
                        def seconds_mms_diff(t0, t1):
                            diff = t1 - t0
                            s = diff.seconds
                            mms = diff.microseconds
                            return float(f"{s}.{mms}")
                        
                        timediffs = []
                        init = timestruct_tuples[0][1]
                        idx = 0
                        while idx < (len(timestruct_tuples)-1):
                            timediffs.append(seconds_mms_diff(init, timestruct_tuples[idx+1][1]))
                            idx += 1
                            init = timestruct_tuples[idx][1]
                        return timediffs
                    

                    【讨论】:

                      猜你喜欢
                      • 2010-10-20
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2018-11-13
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多