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

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


当前回答

我很喜欢保罗·麦奎尔的答案,但我使用的是Python 3。因此,对于感兴趣的人来说:这里是他在*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")

如果你觉得这很有用,你仍然应该投票给他的答案,而不是这一个,因为他做了大部分工作;)。

其他回答

您可以使用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}

我定义了以下Python装饰器:

def profile(fct):
  def wrapper(*args, **kw):
    start_time = time.time()
    ret = fct(*args, **kw)
    print("{} {} {} return {} in {} seconds".format(args[0].__class__.__name__,
                                                    args[0].__class__.__module__,
                                                    fct.__name__,
                                                    ret,
                                                    time.time() - start_time))
    return ret
  return wrapper

并将其用于函数或类/方法:

@profile
def main()
   ...

time.clock在Python 3.3中已被弃用,并将从Python 3.8中删除:请改用time.perf_counter或time.prrocess_time

import time
start_time = time.perf_counter ()
for x in range(1, 100):
    print(x)
end_time = time.perf_counter ()
print(end_time - start_time, "seconds")

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

例如:

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

or

Duration: 1 day, 1:51:24.269711

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

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

我很喜欢保罗·麦奎尔的答案,但我使用的是Python 3。因此,对于感兴趣的人来说:这里是他在*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")

如果你觉得这很有用,你仍然应该投票给他的答案,而不是这一个,因为他做了大部分工作;)。