我想测量执行一个函数所花费的时间。我没时间工作:

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

当前回答

虽然问题中没有严格要求,但通常情况下,您需要一种简单、统一的方法来递增地测量几行代码之间的经过时间。

如果您使用的是Python 3.8或更高版本,则可以使用赋值表达式(也称为walrus运算符)以相当优雅的方式实现这一点:

import time

start, times = time.perf_counter(), {}

print("hello")
times["print"] = -start + (start := time.perf_counter())

time.sleep(1.42)
times["sleep"] = -start + (start := time.perf_counter())

a = [n**2 for n in range(10000)]
times["pow"] = -start + (start := time.perf_counter())

print(times)

=>

{'print': 2.193450927734375e-05, 'sleep': 1.4210970401763916, 'power': 0.005671024322509766}

其他回答

作为lambda,获取经过的时间和时间戳:

import datetime
t_set = lambda: datetime.datetime.now().astimezone().replace(microsecond=0)
t_diff = lambda t: str(t_set() - t)
t_stamp = lambda t=None: str(t) if t else str(t_set())

在实践中:

>>> 
>>> t_set()
datetime.datetime(2021, 3, 21, 1, 25, 17, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=61200), 'PDT'))
>>> t = t_set()
>>> t_diff(t)
'0:00:14'
>>> t_diff(t)
'0:00:23'
>>> t_stamp()
'2021-03-21 01:25:57-07:00'
>>> t_stamp(t)
'2021-03-21 01:25:22-07:00'
>>> 

给定要计时的函数,

测试.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.time或time.clock(天真地)来比较函数的速度。他们会给出误导性的结果。

PS.不要将打印语句放在您希望计时的函数中;否则测量的时间将取决于终端的速度。

使用time.time来测量执行情况,可以获得命令的总体执行时间,包括计算机上其他进程花费的运行时间。这是用户注意到的时候,但如果你想比较不同的代码片段/算法/函数/。。。

有关timeit的更多信息:

使用timeit模块timeit–对少量Python代码的执行进行计时

如果您想深入了解剖析:

http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code如何评测python脚本?

更新:我使用http://pythonhosted.org/line_profiler/在过去的一年中,我们做了很多工作,发现它非常有用,建议使用它来代替Pythons配置文件模块。

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

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

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

这里有一个很好的文档记录和完全类型提示的装饰器,我将其用作通用工具:

from functools import wraps
from time import perf_counter
from typing import Any, Callable, Optional, TypeVar, cast

F = TypeVar("F", bound=Callable[..., Any])


def timer(prefix: Optional[str] = None, precision: int = 6) -> Callable[[F], F]:
    """Use as a decorator to time the execution of any function.

    Args:
        prefix: String to print before the time taken.
            Default is the name of the function.
        precision: How many decimals to include in the seconds value.

    Examples:
        >>> @timer()
        ... def foo(x):
        ...     return x
        >>> foo(123)
        foo: 0.000...s
        123
        >>> @timer("Time taken: ", 2)
        ... def foo(x):
        ...     return x
        >>> foo(123)
        Time taken: 0.00s
        123

    """
    def decorator(func: F) -> F:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            nonlocal prefix
            prefix = prefix if prefix is not None else f"{func.__name__}: "
            start = perf_counter()
            result = func(*args, **kwargs)
            end = perf_counter()
            print(f"{prefix}{end - start:.{precision}f}s")
            return result
        return cast(F, wrapper)
    return decorator

示例用法:

from timer import timer


@timer(precision=9)
def takes_long(x: int) -> bool:
    return x in (i for i in range(x + 1))


result = takes_long(10**8)
print(result)

输出:耗时:4.942629056秒真的

可以通过以下方式检查doctest:

$ python3 -m doctest --verbose -o=ELLIPSIS timer.py

类型提示:

$ mypy timer.py