首页 文章

我如何获得Python程序的执行时间?

提问于
浏览
671

我在Python中有一个命令行程序需要一段时间才能完成 . 我想知道完成跑步所需的确切时间 .

我看过 timeit 模块,但它似乎只适用于小代码片段 . 我想要整个计划的时间 .

24 回答

  • 23

    我喜欢 datetime 模块提供的输出,其中时间delta对象以人类可读的方式显示天,小时,分钟等 .

    例如:

    from datetime import datetime
    start_time = datetime.now()
    # do your work here
    end_time = datetime.now()
    print('Duration: {}'.format(end_time - start_time))
    

    样本输出例如

    Duration: 0:00:08.309267
    

    要么

    Duration: 1 day, 1:51:24.269711
    

    Update: 正如J.F. Sebastian所提到的,这种方法可能会遇到一些当地时间的棘手案例,因此使用起来更安全:

    import time
    from datetime import timedelta
    start_time = time.monotonic()
    end_time = time.monotonic()
    print(timedelta(seconds=end_time - start_time))
    
  • 180

    Python中最简单的方法:

    import time
    start_time = time.time()
    main()
    print("--- %s seconds ---" % (time.time() - start_time))
    

    这假定您的程序至少需要十分之一秒才能运行 .

    打印:

    --- 0.764891862869 seconds ---
    
  • 131

    我把这个 timing.py 模块放到我自己的 site-packages 目录中,只需在我的模块顶部插入 import timing

    import atexit
    from time import clock
    
    def secondsToStr(t):
        return "%d:%02d:%02d.%03d" % \
            reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
                [(t*1000,),1000,60,60])
    
    line = "="*40
    def log(s, elapsed=None):
        print line
        print secondsToStr(clock()), '-', s
        if elapsed:
            print "Elapsed time:", elapsed
        print line
        print
    
    def endlog():
        end = clock()
        elapsed = end-start
        log("End Program", secondsToStr(elapsed))
    
    def now():
        return secondsToStr(clock())
    
    start = clock()
    atexit.register(endlog)
    log("Start Program")
    

    如果我想要显示的程序中有重要的阶段,我也可以从我的程序中调用 timing.log . 但仅包括 import timing 将打印开始和结束时间以及总体经过时间 . (原谅我模糊不清的 secondsToStr 函数,它只是将浮点数秒格式化为hh:mm:ss.sss形式 . )

    注意:可以找到上述代码的Python 3版本herehere .

  • 40

    在Linux或UNIX中:

    time python yourprogram.py
    

    在Windows中,请参阅此Stackoverflow讨论:How to measure execution time of command in windows command line?

  • 7
    import time
    
    start_time = time.clock()
    main()
    print time.clock() - start_time, "seconds"
    

    time.clock() 返回处理器时间,这允许我们仅计算此过程使用的时间(无论如何在Unix上) . 文档说"in any case, this is the function to use for benchmarking Python or timing algorithms"

  • 3

    我非常喜欢Paul McGuire的回答,但我使用的是Python3 . 所以对于那些感兴趣的人:这里是他的答案的修改,适用于* nix上的Python 3(我想,在Windows下,应该使用clock()而不是time()):

    #python3
    import atexit
    from time import time, strftime, localtime
    from datetime import timedelta
    
    def secondsToStr(elapsed=None):
        if elapsed is None:
            return strftime("%Y-%m-%d %H:%M:%S", localtime())
        else:
            return str(timedelta(seconds=elapsed))
    
    def log(s, elapsed=None):
        line = "="*40
        print(line)
        print(secondsToStr(), '-', s)
        if elapsed:
            print("Elapsed time:", elapsed)
        print(line)
        print()
    
    def endlog():
        end = time()
        elapsed = end-start
        log("End Program", secondsToStr(elapsed))
    
    start = time()
    atexit.register(endlog)
    log("Start Program")
    

    如果你觉得这很有用,你应该继续投票给他的答案而不是这个,因为他完成了大部分的工作;) .

  • 8

    您可以使用python profiler cProfile来测量CPU time以及每个函数内部花费的时间以及每个函数的调用次数 . 如果您想要在不知道从哪里开始的情况下提高脚本的性能,这非常有用 . This answer对另一个SO问题非常好 . 看看the docs总是好的 .

    以下是如何使用命令行中的cProfile配置脚本的示例:

    $ python -m cProfile euler048.py
    
    1007 function calls in 0.061 CPU seconds
    
    Ordered by: standard name
    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.061    0.061 <string>:1(<module>)
     1000    0.051    0.000    0.051    0.000 euler048.py:2(<lambda>)
        1    0.005    0.005    0.061    0.061 euler048.py:2(<module>)
        1    0.000    0.000    0.061    0.061 {execfile}
        1    0.002    0.002    0.053    0.053 {map}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler objects}
        1    0.000    0.000    0.000    0.000 {range}
        1    0.003    0.003    0.003    0.003 {sum}
    
  • 6

    对Linux来说更好: /usr/bin/time

    $ /usr/bin/time -v python rhtest2.py
    
        Command being timed: "python rhtest2.py"
        User time (seconds): 4.13
        System time (seconds): 0.07
        Percent of CPU this job got: 91%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:04.58
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 0
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 15
        Minor (reclaiming a frame) page faults: 5095
        Voluntary context switches: 27
        Involuntary context switches: 279
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
    

    通常情况下, time 只是一个更简单的内置内容,可以遮蔽功能更强大的 /usr/bin/time .

  • 2

    rogeriopvl的解决方案工作正常,但如果你想要更具体的信息,你可以使用python内置的分析器 . 查看此页面:

    http://docs.python.org/library/profile.html

    探查器会告诉您许多有用的信息,例如每个功能所花费的时间

  • 4

    以下代码段以一种漂亮的人类可读 <HH:MM:SS> 格式打印已用时间 .

    import time
    from datetime import timedelta
    
    start_time = time.time()
    
    #
    # Perform lots of computations.
    #
    
    elapsed_time_secs = time.time() - start_time
    
    msg = "Execution took: %s secs (Wall clock time)" % timedelta(seconds=round(elapsed_time_secs))
    
    print(msg)
    
  • 10
    from time import time
    start_time = time()
    ...
    end_time = time()
    time_taken = end_time - start_time # time_taken is in seconds
    hours, rest = divmod(time_taken,3600)
    minutes, seconds = divmod(rest, 60)
    
  • 7

    time.clock()

    从版本3.3开始不推荐使用:此函数的行为取决于平台:根据您的要求,使用perf_counter()或process_time()来定义明确的行为 .

    time.perf_counter()

    返回性能计数器的值(以小数秒为单位),即具有最高可用分辨率的时钟,以测量短持续时间 . 它确实包括睡眠期间经过的时间,并且是系统范围的 .

    time.process_time()

    返回当前进程的系统和用户CPU时间总和的值(以小数秒为单位) . 它不包括睡眠期间经过的时间 .

    start = time.process_time()
    ... do something
    elapsed = (time.process_time() - start)
    
  • 2

    我看过timeit模块,但它似乎只适用于小代码片段 . 我想要整个计划的时间 .

    $ python -mtimeit -n1 -r1 -t -s "from your_module import main" "main()"
    

    它运行 your_module.main() 函数一次,并使用 time.time() 函数作为计时器打印已用时间 .

    要在Python中模拟 /usr/bin/time ,请参阅Python subprocess with /usr/bin/time: how to capture timing info but ignore all other output? .

    要测量每个函数的CPU时间(例如,不包括 time.sleep() 期间的时间),可以使用 profile 模块(在Python 2上为 cProfile ):

    $ python3 -mprofile your_module.py
    

    如果要使用与 profile 模块使用的相同的计时器,可以将 -p 传递给上面的 timeit 命令 .

    How can you profile a Python script?

  • 5

    Ipython“timeit”任何脚本:

    def foo():
        %run bar.py
    timeit foo()
    
  • 1

    只需使用 timeit 模块 . 它适用于Python 2和Python 3

    import timeit
    
    start = timeit.default_timer()
    #ALL THE PROGRAM STATEMETNS
    stop = timeit.default_timer()
    execution_time = stop - start
    
    print("Program Executed in "+execution_time) #It returns time in sec
    

    它以秒为单位返回,您可以拥有执行时间 . 很简单,但你应该写这些在Main Function中启动程序执行 . 如果你想获得执行时间,即使你得到错误,然后把你的参数“开始”给它并在那里计算

    def sample_function(start,**kwargs):
         try:
             #your statements
         Except:
             #Except Statements
             stop = timeit.default_timer()
             execution_time = stop - start
             print("Program Executed in "+execution_time)
    
  • 52

    有一个 timeit 模块,可用于计算python代码的执行时间 . 它有python文档中的详细文档和示例(https://docs.python.org/2/library/timeit.html

  • 47

    Python程序的执行措施的时间可能不一致,具体取决于:

    • 可以使用不同的算法评估相同的程序

    • 运行时间因算法而异

    • 运行时间因实施而异

    • 运行时间因计算机而异

    • 基于小输入,无法预测运行时间

    这是因为最有效的方法是使用"Order of Growth"并学习大"O"符号来正确执行,https://en.wikipedia.org/wiki/Big_O_notation

    无论如何,您可以尝试使用这个简单的算法评估任何Python程序在每秒特定计算机计数步骤中的性能:将其调整为您要评估的程序

    import time
    
    now = time.time()
    future = now + 10
    step = 4 # why 4 steps? because until here already 4 operations executed
    while time.time() < future:
        step += 3 # why 3 again? because while loop execute 1 comparison and 1 plus equal statement
    step += 4 # why 3 more? because 1 comparison starting while when time is over plus final assignment of step + 1 and print statement
    print(str(int(step / 10)) + " steps per second")
    

    希望这对你有所帮助 .

  • 0

    我也喜欢Paul McGuire的答案,并提出了一个适合我更多需求的上下文管理器表单 .

    import datetime as dt
    import timeit
    
    class TimingManager(object):
        """Context Manager used with the statement 'with' to time some execution.
    
        Example:
    
        with TimingManager() as t:
           # Code to time
        """
    
        clock = timeit.default_timer
    
        def __enter__(self):
            """
            """
            self.start = self.clock()
            self.log('\n=> Start Timing: {}')
    
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            """
            """
            self.endlog()
    
            return False
    
        def log(self, s, elapsed=None):
            """Log current time and elapsed time if present.
            :param s: Text to display, use '{}' to format the text with
                the current time.
            :param elapsed: Elapsed time to display. Dafault: None, no display.
            """
            print s.format(self._secondsToStr(self.clock()))
    
            if(elapsed is not None):
                print 'Elapsed time: {}\n'.format(elapsed)
    
        def endlog(self):
            """Log time for the end of execution with elapsed time.
            """
            self.log('=> End Timing: {}', self.now())
    
        def now(self):
            """Return current elapsed time as hh:mm:ss string.
            :return: String.
            """
            return str(dt.timedelta(seconds = self.clock() - self.start))
    
        def _secondsToStr(self, sec):
            """Convert timestamp to h:mm:ss string.
            :param sec: Timestamp.
            """
            return str(dt.datetime.fromtimestamp(sec))
    
  • 5

    使用line_profiler .

    line_profiler将分析各行代码执行的时间 . 分析器通过Cython在C中实现,以减少分析的开销 .

    from line_profiler import LineProfiler
    import random
    
    def do_stuff(numbers):
        s = sum(numbers)
        l = [numbers[i]/43 for i in range(len(numbers))]
        m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
    
    numbers = [random.randint(1,100) for i in range(1000)]
    lp = LineProfiler()
    lp_wrapper = lp(do_stuff)
    lp_wrapper(numbers)
    lp.print_stats()
    

    结果将是:

    Timer unit: 1e-06 s
    
    Total time: 0.000649 s
    File: <ipython-input-2-2e060b054fea>
    Function: do_stuff at line 4
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
         4                                           def do_stuff(numbers):
         5         1           10     10.0      1.5      s = sum(numbers)
         6         1          186    186.0     28.7      l = [numbers[i]/43 for i in range(len(numbers))]
         7         1          453    453.0     69.8      m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
    
  • 9

    对于使用Jupyter笔记本的数据人员

    在单元格中,您可以使用Jupyter的 %%time magic命令来测量执行时间:

    %%time 
    [ x**2 for x in range(10000)]
    

    Output
    CPU时间:用户4.54 ms,sys:0 ns,总计:4.54 ms
    壁挂时间:4.12毫秒

    这只会捕获特定单元格的执行时间 . 如果您想捕获整个笔记本(即程序)的执行时间,您可以在同一目录中创建一个新笔记本,并在新笔记本中执行所有单元格:

    假设上面的笔记本被称为 example_notebook.ipynb . 在同一目录中的新笔记本中:

    # Convert your notebook to a .py script:
    !jupyter nbconvert --to script example_notebook.ipynb
    
    # Run the example_notebook with -t flag for time
    %run -t example_notebook
    

    Output
    IPython CPU时序(估计):用户:0.00秒 .
    系统:0.00秒 .
    壁挂时间:0.00秒 .

  • 32

    这是Paul McGuire的回答,对我有用 . 以防有人在运行那个时遇到问题 .

    import atexit
    from time import clock
    
    def reduce(function, iterable, initializer=None):
        it = iter(iterable)
        if initializer is None:
            value = next(it)
        else:
            value = initializer
        for element in it:
            value = function(value, element)
        return value
    
    def secondsToStr(t):
        return "%d:%02d:%02d.%03d" % \
            reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
                [(t*1000,),1000,60,60])
    
    line = "="*40
    def log(s, elapsed=None):
        print (line)
        print (secondsToStr(clock()), '-', s)
        if elapsed:
            print ("Elapsed time:", elapsed)
        print (line)
    
    def endlog():
        end = clock()
        elapsed = end-start
        log("End Program", secondsToStr(elapsed))
    
    def now():
        return secondsToStr(clock())
    
    def main():
        start = clock()
        atexit.register(endlog)
        log("Start Program")
    

    导入文件后,从程序中调用 timing.main() .

  • 1166

    Timeit是python中用于计算小块代码执行时间的类 .

    Default_timer是此类中的一种方法,用于测量挂钟时序而非CPU执行时间 . 因此,其他流程执行可能会干扰这一点 . 因此,它对于小块代码很有用 .

    代码示例如下:

    from timeit import default_timer as timer
    
    start= timer()
    
    #some logic 
    
    end = timer() 
    
    print("Time taken:", end-start)
    
  • 0

    要将metakermit's updated answer用于python 2.7,您将需要monotonic包 .

    代码如下:

    from datetime import timedelta
    from monotonic import monotonic
    
    start_time = monotonic()
    end_time = monotonic()
    print(timedelta(seconds=end_time - start_time))
    
  • 12

    我使用了一个非常简单的函数来计算代码执行的一部分:

    import time
    def timing():
        start_time = time.time()
        return lambda x: print("[{:.2f}s] {}".format(time.time() - start_time, x))
    

    并且要使用它,只需在代码之前调用它来测量以检索计时功能,然后在带有注释的代码之后调用该函数,时间将出现在注释的前面,例如:

    t = timing()
    train = pd.read_csv('train.csv',
                            dtype={
                                'id': str,
                                'vendor_id': str,
                                'pickup_datetime': str,
                                'dropoff_datetime': str,
                                'passenger_count': int,
                                'pickup_longitude': np.float64,
                                'pickup_latitude': np.float64,
                                'dropoff_longitude': np.float64,
                                'dropoff_latitude': np.float64,
                                'store_and_fwd_flag': str,
                                'trip_duration': int,
                            },
                            parse_dates = ['pickup_datetime', 'dropoff_datetime'],
                       )
    t("Loaded {} rows data from 'train'".format(len(train)))
    

    然后输出将如下所示:

    [9.35s] Loaded 1458644 rows data from 'train'
    

    我觉得这样有点优雅 .

相关问题