博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
测量在Python中经过的时间
阅读量:3579 次
发布时间:2019-05-20

本文共 13789 字,大约阅读时间需要 45 分钟。

我想要的是开始在我的代码中的某个地方开始计时,然后获取经过的时间,以衡量执行少量功能所花费的时间。 我认为我使用的模块错误,但是文档对我来说却很混乱。

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

#1楼

cProfile和pstats模块为测量某些功能所经过的时间提供了强大的支持,而不必在现有功能周围添加任何代码。

例如,如果您有python脚本timeFunctions.py:

import timedef hello():    print "Hello :)"    time.sleep(0.1)def thankyou():    print "Thank you!"    time.sleep(0.05)for idx in range(10):    hello()for idx in range(100):    thankyou()

要运行事件探查器并为文件生成统计信息,您可以运行:

python -m cProfile -o timeStats.profile timeFunctions.py

这样做是使用cProfile模块来分析timeFunctions.py中的所有功能,并在timeStats.profile文件中收集统计信息。 请注意,我们不必向现有模块(timeFunctions.py)添加任何代码,并且可以使用任何模块来完成此操作。

拥有stats文件后,可以按以下方式运行pstats模块:

python -m pstats timeStats.profile

这将运行交互式统计浏览器,从而为您提供许多不错的功能。 对于您的特定用例,您可以只检查功能的统计信息。 在我们的示例中,检查这两个功能的统计信息显示以下内容:

Welcome to the profile statistics browser.timeStats.profile% stats hello
timeStats.profile 224 function calls in 6.014 seconds Random listing order was used List reduced from 6 to 1 due to restriction <'hello'> ncalls tottime percall cumtime percall filename:lineno(function) 10 0.000 0.000 1.001 0.100 timeFunctions.py:3(hello)timeStats.profile% stats thankyou
timeStats.profile 224 function calls in 6.014 seconds Random listing order was used List reduced from 6 to 1 due to restriction <'thankyou'> ncalls tottime percall cumtime percall filename:lineno(function) 100 0.002 0.000 5.012 0.050 timeFunctions.py:7(thankyou)

这个虚拟的例子并没有做太多,但是让您知道可以做什么。 关于这种方法的最好之处在于,我不必编辑任何现有代码即可获得这些数字,并且显然可以帮助进行性能分析。


#2楼

仅限Python 3:

由于从使用 ,因此您将需要使用进行系统范围的计时,或者使用 进行进程范围的计时,就像您以前使用time.clock()

import timet = time.process_time()#do some stuffelapsed_time = time.process_time() - t

新函数process_time将不包括睡眠期间经过的时间。


#3楼

使用timeit.default_timer而不是timeit.timeit 。 前者会自动在您的平台和Python版本上提供最佳时钟:

from timeit import default_timer as timerstart = timer()# ...end = timer()print(end - start) # Time in seconds, e.g. 5.38091952400282

根据操作系统,将分配给time.time()或time.clock()。 在Python 3.3+上,在所有平台上, 是 。 参见

也可以看看:


#4楼

(仅对于Ipython)可以使用来衡量平均处理时间:

def foo():    print "hello"

然后:

%timeit foo()

结果是这样的:

10000 loops, best of 3: 27 µs per loop

#5楼

使用上下文管理器执行此操作很有趣,它可以自动记住进入with块的开始时间,然后冻结块退出时的结束时间。 只需一点技巧,您甚至可以通过相同的上下文管理器功能在块内获得运行时间计数。

核心库没有这个(但应该这样做)。 放置到位后,您可以执行以下操作:

with elapsed_timer() as elapsed:    # some lengthy code    print( "midpoint at %.2f seconds" % elapsed() )  # time so far    # other lengthy codeprint( "all done at %.2f seconds" % elapsed() )

这是足以完成此任务的代码:

from contextlib import contextmanagerfrom timeit import default_timer@contextmanagerdef elapsed_timer():    start = default_timer()    elapser = lambda: default_timer() - start    yield lambda: elapser()    end = default_timer()    elapser = lambda: end-start

还有一些可运行的演示代码:

import timewith elapsed_timer() as elapsed:    time.sleep(1)    print(elapsed())    time.sleep(2)    print(elapsed())    time.sleep(3)

请注意,通过设计此函数, elapsed()的返回值在块退出时被冻结,并且进一步的调用返回相同的持续时间(在此玩具示例中约为6秒)。


#6楼

我为此创建了一个库,如果您想测量一个函数,可以像这样做

from pythonbenchmark import compare, import timea,b,c,d,e = 10,10,10,10,10something = [a,b,c,d,e]@measuredef myFunction(something):    time.sleep(0.4)@measuredef myOptimizedFunction(something):    time.sleep(0.2)myFunction(input)myOptimizedFunction(input)


#7楼

在python3上:

from time import sleep, perf_counter as pct0 = pc()sleep(1)print(pc()-t0)

优雅而短暂。


#8楼

这是一个微小的计时器类,它返回“ hh:mm:ss”字符串:

class Timer:  def __init__(self):    self.start = time.time()  def restart(self):    self.start = time.time()  def get_time_hhmmss(self):    end = time.time()    m, s = divmod(end - self.start, 60)    h, m = divmod(m, 60)    time_str = "%02d:%02d:%02d" % (h, m, s)    return time_str

用法:

# Start timermy_timer = Timer()# ... do something# Get time string:time_hhmmss = my_timer.get_time_hhmmss()print("Time elapsed: %s" % time_hhmmss )# ... use the timer againmy_timer.restart()# ... do something# Get time:time_hhmmss = my_timer.get_time_hhmmss()# ... etc

#9楼

我们还可以将时间转换为人类可以理解的时间。

import time, datetimestart = time.clock()def num_multi1(max):    result = 0    for num in range(0, 1000):        if (num % 3 == 0 or num % 5 == 0):            result += num    print "Sum is %d " % resultnum_multi1(1000)end = time.clock()value = end - starttimestamp = datetime.datetime.fromtimestamp(value)print timestamp.strftime('%Y-%m-%d %H:%M:%S')

#10楼

使用一种方法:

from timeit import timeitdef func():    return 1 + 1time = timeit(func, number=1)print(time)

#11楼

这是另一个用于计时代码的上下文管理器-

用法:

from benchmark import benchmarkwith benchmark("Test 1+1"):    1+1=>Test 1+1 : 1.41e-06 seconds

或者,如果您需要时间值

with benchmark("Test 1+1") as b:    1+1print(b.time)=>Test 1+1 : 7.05e-07 seconds7.05233786763e-07

Benchmark.py

from timeit import default_timer as timerclass benchmark(object):    def __init__(self, msg, fmt="%0.3g"):        self.msg = msg        self.fmt = fmt    def __enter__(self):        self.start = timer()        return self    def __exit__(self, *args):        t = timer() - self.start        print(("%s : " + self.fmt + " seconds") % (self.msg, t))        self.time = t

改编自


#12楼

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

如果function没有任何参数,则不需要包装函数。


#13楼

使用探查器模块。 它提供了非常详细的配置文件。

import profileprofile.run('main()')

它输出类似:

5 function calls in 0.047 seconds   Ordered by: standard name   ncalls  tottime  percall  cumtime  percall filename:lineno(function)        1    0.000    0.000    0.000    0.000 :0(exec)        1    0.047    0.047    0.047    0.047 :0(setprofile)        1    0.000    0.000    0.000    0.000 
:1(
) 0 0.000 0.000 profile:0(profiler) 1 0.000 0.000 0.047 0.047 profile:0(main()) 1 0.000 0.000 0.000 0.000 two_sum.py:2(twoSum)

我发现它非常有用。


#14楼

我喜欢这个。 timeit文档太混乱了。

from datetime import datetime start_time = datetime.now() # INSERT YOUR CODE time_elapsed = datetime.now() - start_time print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))

注意,这里没有任何格式,我只是在打印输出中写了hh:mm:ss以便可以解释time_elapsed


#15楼

有点超级后来的反应,但也许对某人有用。 我认为这是一种超级干净的方法。

import timedef timed(fun, *args):    s = time.time()    r = fun(*args)    print('{} execution took {} seconds.'.format(fun.__name__, time.time()-s))    return(r)timed(print, "Hello")

请记住,“ print”是Python 3中的功能,而不是Python 2.7中的功能。 但是,它可以与任何其他功能一起使用。 干杯!


#16楼

我能想到的唯一方法是使用time.time()

import timestart = time.time()sleep(5) #just to give it some delay to show it workingfinish = time.time()elapsed = finish - startprint(elapsed)

希望会有所帮助。


#17楼

这是我在这里经过许多不错的回答以及其他几篇文章后的发现。

首先,您总是要使用timeit而不是time.time (在许多情况下是perf计数器API),因为

  1. timeit选择适用于您的OS和Python版本的最佳计时器。
  2. timeit禁用垃圾收集,但这不是您可能想要或可能不需要的东西。

现在的问题是,timetime并不是那么简单易用,因为它需要设置,并且当您进行大量导入时,事情变得很丑陋。 理想情况下,你只想要一个装饰或者使用with块和测量时间。 不幸的是,对此没有内置的功能,因此我在小实用程序模块下面创建了该模块。

计时实用程序模块

# utils.pyfrom functools import wrapsimport gcimport timeitdef MeasureTime(f):    @wraps(f)    def _wrapper(*args, **kwargs):        gcold = gc.isenabled()        gc.disable()        start_time = timeit.default_timer()        try:            result = f(*args, **kwargs)        finally:            elapsed = timeit.default_timer() - start_time            if gcold:                gc.enable()            print('Function "{}": {}s'.format(f.__name__, elapsed))        return result    return _wrapperclass MeasureBlockTime:    def __init__(self,name="(block)", no_print = False, disable_gc = True):        self.name = name        self.no_print = no_print        self.disable_gc = disable_gc    def __enter__(self):        if self.disable_gc:            self.gcold = gc.isenabled()            gc.disable()        self.start_time = timeit.default_timer()    def __exit__(self,ty,val,tb):        self.elapsed = timeit.default_timer() - self.start_time        if self.disable_gc and self.gcold:            gc.enable()        if not self.no_print:            print('Function "{}": {}s'.format(self.name, self.elapsed))        return False #re-raise any exceptions

如何计时功能

现在,您只需在其前面放置装饰器即可计时任何功能:

import utils@utils.MeasureTimedef MyBigFunc():    #do something time consuming    for i in range(10000):        print(i)

如何计时代码块

如果您想计时部分代码,只需将其with代码块with放入:

import utils#somewhere in my codewith utils.MeasureBlockTime("MyBlock"):    #do something time consuming    for i in range(10000):        print(i)# rest of my code

好处

有几个半支持的版本,所以我想指出一些重点:

  1. 出于前面所述的原因,请使用timeit中的timer代替time.time。
  2. 在计时期间禁用GC。
  3. 装饰器接受带有已命名或未命名参数的函数。
  4. 能够按块定时禁用打印( with utils.MeasureBlockTime() as t使用,然后为t.elapsed )。
  5. 能够为块定时保持启用gc的能力。

#18楼

最好简单地使用timeit :(它对同一命令运行多个运行并为您提供结果)。

示例如下:

%timeit import pandas as pd

#19楼

除了ipython中的 %timeit ,您还可以将%%timeit用于多行代码段:

In [1]: %%timeit   ...: complex_func()   ...: 2 + 2 == 5   ...:   ...:1 s ± 1.93 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

也可以以相同的方式在jupyter笔记本中使用,只需将放在单元格的开头即可。


#20楼

以秒为单位的测量时间

from timeit import default_timer as timerfrom datetime import timedeltastart = timer()end = timer()print(timedelta(seconds=end-start))

输出

0:00:01.946339

#21楼

要了解每个函数的递归调用,请执行以下操作:

%load_ext snakeviz%%snakeviz

它只需在Jupyter笔记本中使用这两 行代码 ,并生成一个漂亮的交互式图表。 例如:

这是代码。 同样,以%开头的2行是使用snakeviz所需的仅有的额外代码行:

# !pip install snakeviz%load_ext snakevizimport globimport hashlib%%snakevizfiles = glob.glob('*.txt')def print_files_hashed(files):    for file in files:        with open(file) as f:            print(hashlib.md5(f.read().encode('utf-8')).hexdigest())print_files_hashed(files)

在笔记本外运行snakeviz也似乎是可能的。 在上有更多信息。


#22楼

我喜欢它简单 (python 3):

from timeit import timeittimeit(lambda: print("hello"))

单个执行的输出为微秒

2.430883963010274

说明 :timeit默认执行匿名函数一百万次 ,结果以秒为单位 。 因此, 单次执行的结果是相同的数量,但平均为微秒


对于缓慢的操作添加较低数量的迭代,或者你可能会永远等待:

import timetimeit(lambda: time.sleep(1.5), number=1)

输出总是在为迭代的总数目

1.5015795179999714

#23楼

现在是2019年。 让我们以一种简洁的方式做到这一点:

from ttictoc import TicToct = TicToc() ## TicToc("name")t.tic();# your code ...t.toc();print(t.elapsed)

使用此方法而不是其他方法的优点:

  1. 简洁明了。 它不需要程序员编写额外的变量,例如:
    t1 =时间()
    t2 =时间()
    经过时间= t2-t1
  2. 带嵌套
t = TicToc(nested=True)t.tic()some code1...t.tic()some code2...t.tic()some code3...print(t.toc()) # Prints time for code 3 print(t.toc()) # Prints time for code 2 with code 3print(t.toc()) # Prints time for code 1 with code 2 and 3
  1. 保留井字游戏的名称。
t = TicToc("save user")print(t.name)

请参考此以获取更多详细说明。


#24楼

这种独特的基于类的方法提供了可打印的字符串表示形式,可自定义的舍入功能,并且可以方便地访问作为字符串或浮点数的经过时间。 它是使用Python 3.7开发的。

import datetimeimport timeitclass Timer:    """Measure time used."""    # Ref: https://stackoverflow.com/a/57931660/    def __init__(self, round_ndigits: int = 0):        self._round_ndigits = round_ndigits        self._start_time = timeit.default_timer()    def __call__(self) -> float:        return timeit.default_timer() - self._start_time    def __str__(self) -> str:        return str(datetime.timedelta(seconds=round(self(), self._round_ndigits)))

用法:

>>> timer = Timer()>>> # Access as a string>>> print(f'Time elapsed is {timer}.')Time elapsed is 0:00:03.>>> print(f'Time elapsed is {timer}.')Time elapsed is 0:00:04.>>> # Access as a float>>> timer()6.841332235>>> timer()7.970274425

#25楼

import timedef 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)

#26楼

timeit模块非常适合计时一小段Python代码。 它至少可以以三种形式使用:

1-作为命令行模块

python2 -m timeit 'for i in xrange(10): oct(i)'

2-对于短代码,请将其作为参数传递。

import timeittimeit.Timer('for i in xrange(10): oct(i)').timeit()

3-对于更长的代码为:

import timeitcode_to_test = """a = range(100000)b = []for i in a:    b.append(i*2)"""elapsed_time = timeit.timeit(code_to_test, number=100)/100print(elapsed_time)

#27楼

如果只想测量两点之间经过的挂钟时间,则可以使用 :

import timestart = time.time()print("hello")end = time.time()print(end - start)

这给出了执行时间(以秒为单位)。

自3.3起,另一个选择可能是使用或 ,具体取决于您的要求。 在3.3之前,建议使用 (感谢 )。 但是,目前不推荐使用:

在Unix上,以秒为单位返回当前处理器时间,以浮点数表示。 精度,实际上是“处理器时间”含义的确切定义,取决于同名C函数的精度。

在Windows上,此函数基于Win32函数QueryPerformanceCounter()返回自第一次调用此函数以来经过的时间(以秒为单位)的浮点数。 分辨率通常优于一微秒。

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


#28楼

使用time.time来衡量执行情况可以为您提供命令的总体执行时间,包括计算机上其他进程所花费的运行时间。 这是用户注意到的时间,但是如果您要比较不同的代码段/算法/函数/ ...,则效果不佳。

有关timeit更多信息:

如果您想对配置文件有更深入的了解:

更新 :去年我大量使用了 ,发现它非常有用,建议使用它代替Pythons profile模块。


#29楼

有了您想计时的功能,

test.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.timetime.clock来比较功能的速度。 。

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

转载地址:http://brogj.baihongyu.com/

你可能感兴趣的文章
matlab中 %d,%f,%c,%s
查看>>
常见的光纤接头汇总
查看>>
半导体激光器—问题整理(二)
查看>>
科研日记7.31
查看>>
zemax仿真二向色镜
查看>>
stm32单片机编程时extern的用法
查看>>
UART4和5的问题
查看>>
Spring框架中在并发访问时的线程安全性
查看>>
网站部署
查看>>
什么情况下会发生栈内存溢出。
查看>>
何为去中心化
查看>>
缓存一致性:写策略
查看>>
Cache一致性:MESI
查看>>
缓存一致性:写未命中
查看>>
为什么用中间位作为组索引
查看>>
缓存:局部性
查看>>
mysql原理:b+树索引
查看>>
mysql原理:最左原则
查看>>
mysql原理:join标到底是什么,为什么有军规不建议超过三个
查看>>
redis缓存穿透
查看>>