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

我看过timeit模块,但它似乎只适用于小代码片段。我想给整个节目计时。


当前回答

根据这个答案,创建了一个简单但方便的工具。

import time
from datetime import timedelta

def start_time_measure(message=None):
    if message:
        print(message)
    return time.monotonic()

def end_time_measure(start_time, print_prefix=None):
    end_time = time.monotonic()
    if print_prefix:
        print(print_prefix + str(timedelta(seconds=end_time - start_time)))
    return end_time

用法:

total_start_time = start_time_measure()    
start_time = start_time_measure('Doing something...')
# Do something
end_time_measure(start_time, 'Done in: ')
start_time = start_time_measure('Doing something else...')
# Do something else
end_time_measure(start_time, 'Done in: ')
end_time_measure(total_start_time, 'Total time: ')

输出:

Doing something...
Done in: 0:00:01.218000
Doing something else...
Done in: 0:00:01.313000
Total time: 0:00:02.672000

其他回答

我也喜欢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))

您可以使用Python分析器cProfile来测量CPU时间,以及每个函数内部花费的时间以及每个函数被调用的次数。如果您想在不知道从哪里开始的情况下提高脚本的性能,这非常有用。对另一个堆栈溢出问题的回答很好。查看文档总是很好的。

以下是如何从命令行使用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}
import time

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

time.clock()返回处理器时间,它允许我们仅计算此进程使用的时间(无论如何,在Unix上)。文档中说“无论如何,这是用于Python基准测试或计时算法的函数”

Timeit是Python中的一个类,用于计算小代码块的执行时间。

Default_timer是此类中的一个方法,用于测量墙上时钟计时,而不是CPU执行时间。因此,其他进程执行可能会对此产生干扰。因此,它对小代码块很有用。

代码示例如下:

from timeit import default_timer as timer

start= timer()

# Some logic

end = timer()

print("Time taken:", end-start)

有一个timeit模块,可用于对Python代码的执行时间进行计时。

它在Python文档26.6中有详细的文档和示例。timeit-测量小代码片段的执行时间。