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

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

当前回答

import time

def getElapsedTime(startTime, units):
    elapsedInSeconds = time.time() - startTime
    if units == 'sec':
        return elapsedInSeconds
    if units == 'min':
        return elapsedInSeconds/60
    if units == 'hour':
        return elapsedInSeconds/(60*60)

其他回答

你可以使用timeit。

下面是一个示例,说明如何使用Python REPL测试naive_func,该函数接受参数:

>>> import timeit                                                                                         

>>> def naive_func(x):                                                                                    
...     a = 0                                                                                             
...     for i in range(a):                                                                                
...         a += i                                                                                        
...     return a                                                                                          

>>> def wrapper(func, *args, **kwargs):                                                                   
...     def wrapper():                                                                                    
...         return func(*args, **kwargs)                                                                  
...     return wrapper                                                                                    

>>> wrapped = wrapper(naive_func, 1_000)                                                                  

>>> timeit.timeit(wrapped, number=1_000_000)                                                              
0.4458435332577161  

若函数并没有任何参数,那个么就不需要包装函数。

给定要计时的函数,

测试.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.不要将打印语句放在您希望计时的函数中;否则测量的时间将取决于终端的速度。

对于Python 3

如果使用时间模块,则可以获取当前时间戳,然后执行代码,然后再次获取时间戳。现在,所用时间将是第一个时间戳减去第二个时间戳:

import time

first_stamp = int(round(time.time() * 1000))

# YOUR CODE GOES HERE
time.sleep(5)

second_stamp = int(round(time.time() * 1000))

# Calculate the time taken in milliseconds
time_taken = second_stamp - first_stamp

# To get time in seconds:
time_taken_seconds = round(time_taken / 1000)
print(f'{time_taken_seconds} seconds or {time_taken} milliseconds')

print_elapsed_time函数如下

def print_elapsed_time(prefix=''):
    e_time = time.time()
    if not hasattr(print_elapsed_time, 's_time'):
        print_elapsed_time.s_time = e_time
    else:
        print(f'{prefix} elapsed time: {e_time - print_elapsed_time.s_time:.2f} sec')
        print_elapsed_time.s_time = e_time

用这种方式

print_elapsed_time()
.... heavy jobs ...
print_elapsed_time('after heavy jobs')
.... tons of jobs ...
print_elapsed_time('after tons of jobs')

结果是

after heavy jobs elapsed time: 0.39 sec
after tons of jobs elapsed time: 0.60 sec  

这个函数的优点和缺点是你不需要经过开始时间

我参加聚会已经很晚了,但这种方法以前没有涉及过。当我们想要手动对某段代码进行基准测试时,我们可能需要首先找出哪些类方法占用了执行时间,这有时并不明显。我构建了以下元类来解决这个问题:

from __future__ import annotations

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

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


def timed_method(func: F, prefix: str | None = None) -> F:
    prefix = (prefix + ' ') if prefix else ''

    @wraps(func)
    def inner(*args, **kwargs):  # type: ignore
        start = time()
        try:
            ret = func(*args, **kwargs)
        except BaseException:
            print(f'[ERROR] {prefix}{func.__qualname__}: {time() - start}')
            raise
        
        print(f'{prefix}{func.__qualname__}: {time() - start}')
        return ret

    return cast(F, inner)


class TimedClass(type):
    def __new__(
        cls: type[TimedClass],
        name: str,
        bases: tuple[type[type], ...],
        attrs: dict[str, Any],
        **kwargs: Any,
    ) -> TimedClass:
        for name, attr in attrs.items():
            if isinstance(attr, (classmethod, staticmethod)):
                attrs[name] = type(attr)(timed_method(attr.__func__))
            elif isinstance(attr, property):
                attrs[name] = property(
                    timed_method(attr.fget, 'get') if attr.fget is not None else None,
                    timed_method(attr.fset, 'set') if attr.fset is not None else None,
                    timed_method(attr.fdel, 'del') if attr.fdel is not None else None,
                )
            elif callable(attr):
                attrs[name] = timed_method(attr)

        return super().__new__(cls, name, bases, attrs)

它允许如下使用:

class MyClass(metaclass=TimedClass):
    def foo(self): 
        print('foo')
    
    @classmethod
    def bar(cls): 
        print('bar')
    
    @staticmethod
    def baz(): 
        print('baz')
    
    @property
    def prop(self): 
        print('prop')
    
    @prop.setter
    def prop(self, v): 
        print('fset')
    
    @prop.deleter
    def prop(self): 
        print('fdel')


c = MyClass()

c.foo()
c.bar()
c.baz()
c.prop
c.prop = 2
del c.prop

MyClass.bar()
MyClass.baz()

它打印:

foo
MyClass.foo: 1.621246337890625e-05
bar
MyClass.bar: 4.5299530029296875e-06
baz
MyClass.baz: 4.291534423828125e-06
prop
get MyClass.prop: 3.814697265625e-06
fset
set MyClass.prop: 3.5762786865234375e-06
fdel
del MyClass.prop: 3.5762786865234375e-06
bar
MyClass.bar: 3.814697265625e-06
baz
MyClass.baz: 4.0531158447265625e-06

它可以与其他答案相结合,以更精确的方式代替time.time。