Python'da geçen süre nasıl ölçülür?


1208

Ne istediğim benim kodu bir yerde zaman sayma başlamak ve daha sonra birkaç işlevi yürütmek için gereken süreyi ölçmek için geçirilen zaman almaktır. Sanırım timeit modülünü yanlış kullanıyorum, ancak dokümanlar benim için kafa karıştırıcı.

import timeit

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

Yanıtlar:


1454

Sadece iki nokta arasındaki geçen duvar saati süresini ölçmek istiyorsanız, şunları kullanabilirsiniz time.time():

import time

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

Bu, yürütme süresini saniye olarak verir.

3.3'ten beri başka bir seçenek , gereksinimlerinize bağlı olarak perf_counterveya kullanmak olabilir process_time. 3.3'ten önce kullanılması tavsiye edildi time.clock(teşekkürler Amber ). Ancak şu anda kullanımdan kaldırılmıştır:

Unix'te, geçerli işlemci süresini saniye cinsinden ifade edilen kayan noktalı sayı olarak döndürün. Kesinlik ve aslında “işlemci zamanı” anlamının tanımı, aynı ismin C fonksiyonununkine bağlıdır.

Windows'ta bu işlev, Win32 işlevine dayalı olarak bu noktaya kayan nokta numarası olarak yapılan ilk çağrıdan bu yana geçen duvar saati saniyelerini döndürür QueryPerformanceCounter(). Çözünürlük tipik olarak bir mikrosaniyeden daha iyidir.

Sürüm 3.3'ten bu yana kullanımdan kaldırılmıştır : Bu işlevin davranışı platforma bağlıdır: İyi tanımlanmış bir davranışa sahip olmak için gereksinimlerinize bağlı olarak kullanın perf_counter()veya process_time()kullanın .


17
ve mikrosaniye için datetime.time ()
Inca

110
(Performans ölçümü için, time.clock()aslında tercih edilir, çünkü sistem saati karışırsa müdahale edilemez, ancak .time()çoğunlukla aynı amacı yerine getirir.)
Amber

4
Ben daha fazla kez çalışır ve python zaman ölçmek için yerel bir yol olarak inşa python -mtimeit çok daha iyi olduğunu düşünüyorum
Visgean Skeloru

4
Saniye cinsinden sonuçlanan yürütme süresini HH: MM :: SS gibi bir şeye dönüştürmenin güzel bir yolu var mı?
Danijel

12
@Danijel: print(timedelta(seconds=execution_time)). Bu ayrı bir soru olmasına rağmen.
jfs

688

Yerine timeit.default_timerkullanın timeit.timeit. Birincisi, platformunuzda ve Python sürümünüzde mevcut olan en iyi saati otomatik olarak sağlar:

from timeit import default_timer as timer

start = timer()
# ...
end = timer()
print(end - start) # Time in seconds, e.g. 5.38091952400282

timeit.default_timer , işletim sistemine bağlı olarak time.time () veya time.clock () öğesine atanır. Python Açık 3.3+ default_timer olan time.perf_counter () tüm platformlarda. Bkz. Python - time.clock () ile time.time () - doğruluk?

Ayrıca bakınız:


28
Mükemmel cevap - kullanan sürümüyle gelen timeit çöp toplama ve işletim sistemi farklılıkları gibi şeyler için otomatik hesap olacağından çok daha doğru sonuçlar üretecek
lkgarrison

1
Bu, ms veya saniye cinsinden zaman verir mi?
Katie

3
@KhushbooTiwari kesirli saniye içinde.
jfs

5
Resmi belgelerden bu notun eklenmesi gerektiğini düşünüyorumdefault_timer() measurations can be affected by other programs running on the same machine, so the best thing to do when accurate timing is necessary is to repeat the timing a few times and use the best time. The -r option is good for this; the default of 3 repetitions is probably enough in most cases. On Unix, you can use time.clock() to measure CPU time.
KGS

1
@KGS: Performans ölçümü ince bir şekilde çok zor (kendinizi yanıltmak kolaydır). Burada konuyla ilgili olabilecek daha birçok yorum var. Cevaptaki bağlantıları izleyin. Aynı arabirimi sağlayan perfmodülle de ilgilenebilirsiniz (yanıt anında yok) , ancak bazen timeitzaman performansının nasıl ölçüleceğine dair modül kararlarından farklı olabilir .
jfs

129

Yalnızca Python 3:

Time.clock () , Python 3.3'ten itibaren kullanımdan kaldırıldığından , time.perf_counter()sistem genelinde zamanlama veya time.process_time()işlem genelinde zamanlama için, eskiden kullandığınız şekilde kullanmak istersiniz time.clock():

import time

t = time.process_time()
#do some stuff
elapsed_time = time.process_time() - t

Yeni işlev process_time, uyku sırasında geçen süreyi içermez.


28
Yerinetimeit.default_timer kullanın time.perf_counter. Birincisi, platformunuz ve Python sürümünüz için ayarlanan zaman performansını ölçmek için uygun zamanlayıcıyı seçecektir. process_time()yapar olmayan uyku sırasında zaman alır ve bu yüzden geçen zamanı ölçmek için uygun değildir.
jfs

2
Pierre tarafından önerilen uygulamayı kullanıyorum, saniyeler içinde verilen değerler mi?
ugotchi

Bu cevap konu dışı görünüyor (soru çok spesifik değildi). İki "zaman" ölçümü vardır: işlemin işlemci tüketiminin iki nokta arasındaki duvar saati zamanı.
Franklin Piat

87

Zamanlamak istediğiniz bir işlev verildiğinde,

test.py:

def foo(): 
    # print "hello"   
    return "hello"

kullanmanın en kolay yolu timeitonu komut satırından çağırmaktır:

% python -mtimeit -s'import test' 'test.foo()'
1000000 loops, best of 3: 0.254 usec per loop

İşlevlerin hızını karşılaştırmak için time.timeveya time.clock(safça) kullanmaya çalışmayın . Yanıltıcı sonuçlar verebilirler .

PS. Yazdırma ifadelerini zamanlamak istediğiniz bir işleve koymayın; aksi halde ölçülen süre terminalin hızına bağlı olacaktır .


65

Bunu, bir withbloğa girdikten sonra başlangıç ​​zamanını otomatik olarak hatırlayan , ardından blok çıkışındaki bitiş zamanını donduran bir bağlam yöneticisi ile yapmak eğlencelidir . Küçük bir hile ile, aynı bağlam yöneticisi işlevinden blok içinde geçen bir süre çetelesi bile alabilirsiniz.

Çekirdek kütüphanede bu yoktur (ama muhtemelen olması gerekir). Yerine yerleştiğinde, aşağıdakileri yapabilirsiniz:

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

print( "all done at %.2f seconds" % elapsed() )

İşte hile yapmak için yeterli bağlam yöneticisi kodu:

from contextlib import contextmanager
from timeit import default_timer

@contextmanager
def elapsed_timer():
    start = default_timer()
    elapser = lambda: default_timer() - start
    yield lambda: elapser()
    end = default_timer()
    elapser = lambda: end-start

Ve bazı çalıştırılabilir demo kodları:

import time

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

Bu fonksiyonun tasarımı ile elapsed(), blok çıkışında dönüş değeri dondurulur ve sonraki çağrılar aynı süreyi döndürür (bu oyuncak örneğinde yaklaşık 6 saniye).


2
Diğer bağlam yöneticisi örneği: dabeaz.blogspot.fr/2010/02/…
Jérôme

1
@ Jérôme güzel bir örnek - Başka bir cevap olarak uyarladım - stackoverflow.com/a/41408510/243392
Brian Burns

62

Saniye cinsinden ölçüm süresi :

from timeit import default_timer as timer
from datetime import timedelta

start = timer()
end = timer()
print(timedelta(seconds=end-start))

Çıktı :

0:00:01.946339

1
Bu en temiz çıktı ile en özlü cevaptır.
Dave Liu

56

Bunu tercih ederim. timeitdoc çok kafa karıştırıcı.

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

Burada herhangi bir biçimlendirme olmadığına dikkat edin, çıktıya yazdım hh:mm:ss, böylece biri yorumlayabilirtime_elapsed


Timeit'in CPU zamanını hesapladığı, datetime'ın kullanılan CPU zamanını da dikkate aldığı söylendi? Bunlar aynı şey mi?
Sreehari R

3
Geçen zamanı bu şekilde ölçmek risklidir çünkü datetime.now (), ağ saati senkronizasyonu, gün ışığından yararlanma geçişi veya saati döndüren kullanıcı gibi nedenlerle iki çağrı arasında değişebilir.
user1318499

45

İşte bunu yapmanın başka bir yolu:

>> from pytictoc import TicToc
>> t = TicToc() # create TicToc instance
>> t.tic() # Start timer
>> # do something
>> t.toc() # Print elapsed time
Elapsed time is 2.612231 seconds.

Geleneksel yolla karşılaştırma:

>> from time import time
>> t1 = time()
>> # do something
>> t2 = time()
>> elapsed = t2 - t1
>> print('Elapsed time is %f seconds.' % elapsed)
Elapsed time is 2.612231 seconds.

Kurulum:

pip install pytictoc

Daha fazla bilgi için PyPi sayfasına bakınız.


13
Bu kütüphaneyi kullanmanın diğer yaklaşımlara göre avantajını açıklamak iyi olur.
hlg

Yuvalanmış işlevsellik aslında bozuk. Kodda sorunun nerede olduğunu açıklayan bir sorun açtım ama repo bir yıl içinde korunmadı bu yüzden bir değişiklik beklemem.
PetarMI

Yuvalamayı biraz kafa karıştırıcı buluyorum. Kodda t.tic()gömülü olsaydım, dizide nerede olmasını beklemem gerektiğinin zihinsel bir listesini tutmak geliştiriciye kalmış. Kendinizi yuvalar mı yoksa sadece birden fazla tictok oluşturuyor musunuz?
ScottieB

1
@PetarMI: FYI, sorunu çözdüm ttictoc. Oldukça büyük bir karmaşa vardı, ama şimdi iyi olmalı.
H. Sánchez

33

Burada birkaç iyi makalenin yanı sıra birçok iyi cevaptan geçtikten sonra bulgularım.

İlk olarak, timeitve arasında tartışıyorsanız time.time, timeitbunun iki avantajı vardır:

  1. timeit işletim sisteminizde ve Python sürümünüzde bulunan en iyi zamanlayıcıyı seçer.
  2. timeit çöp toplamayı devre dışı bırakır, ancak bu isteyebileceğiniz veya istemeyeceğiniz bir şey değildir.

Şimdi sorun timeito kadar basit değil çünkü kurulum gerekiyor ve bir sürü ithalatınız olduğunda işler çirkinleşiyor. İdeal olarak, sadece bir dekoratör istersiniz veyawith blok ve ölçüm süresini kullanırsınız. Ne yazık ki, bunun için yerleşik bir şey yok, bu yüzden iki seçeneğiniz var:

1. Seçenek: Zaman çizelgesi kitaplığını kullanma

Timebudget yüklemek pip sonra bir satır kod sadece kullanabilecekleri çok yönlü ve çok basit bir kütüphanedir.

@timebudget  # Record how long this function takes
def my_method():
    # my code

2. Seçenek: Kod modülünü doğrudan kullanın

Aşağıda küçük yarar modülünü oluşturdum.

# utils.py
from functools import wraps
import gc
import timeit

def MeasureTime(f, no_print=False, disable_gc=False):
    @wraps(f)
    def _wrapper(*args, **kwargs):
        gcold = gc.isenabled()
        if disable_gc:
            gc.disable()
        start_time = timeit.default_timer()
        try:
            result = f(*args, **kwargs)
        finally:
            elapsed = timeit.default_timer() - start_time
            if disable_gc and gcold:
                gc.enable()
            if not no_print:
                print('"{}": {}s'.format(f.__name__, elapsed))
        return result
    return _wrapper

class MeasureBlockTime:
    def __init__(self,name="(block)", no_print=False, disable_gc=False):
        self.name = name
        self.no_print = no_print
        self.disable_gc = disable_gc
    def __enter__(self):
        self.gcold = gc.isenabled()
        if self.disable_gc:
            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

Şimdi sadece önünde bir dekoratör koyarak herhangi bir işlevi zamanlayabilirsiniz:

import utils

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

Kodun bir kısmını zamanlamak istiyorsanız, withbloğun içine koyun :

import utils

#somewhere in my code

with utils.MeasureBlockTime("MyBlock"):
    #do something time consuming
    for i in range(10000):
        print(i)

# rest of my code

Avantajları:

Birkaç vurgulamak işaret etmek istiyorum etrafında yüzen birkaç yarı destekli sürümleri vardır:

  1. Daha önce açıklanan nedenler için zamanlayıcıyı time.time yerine timeit'den kullanın.
  2. İsterseniz zamanlama sırasında GC'yi devre dışı bırakabilirsiniz.
  3. Dekoratör adlandırılmış veya adlandırılmamış parametrelerle işlevleri kabul eder.
  4. Blok zamanlamasında yazdırmayı devre dışı bırakma özelliği ( with utils.MeasureBlockTime() as tve sonra kullanın t.elapsed).
  5. Blok zamanlaması için gc'yi etkin tutma yeteneği.

28

Yürütmeyi time.timeölçmek için kullanmak , bilgisayarınızdaki diğer işlemler tarafından harcanan çalışma süresi de dahil olmak üzere komutlarınızın genel yürütme süresini verir. Bu, kullanıcının fark ettiği zamandır, ancak farklı kod snippet'lerini / algoritmaları / fonksiyonları / karşılaştırmak istiyorsanız iyi değildir ...

Hakkında daha fazla bilgi timeit:

Profil oluşturma hakkında daha derin bir fikir edinmek istiyorsanız:

Güncelleme : Geçen yıl http://pythonhosted.org/line_profiler/ çok kullandım ve çok yararlı buldum ve Pythons profil modülü yerine kullanmanızı tavsiye ederim.


19

İşte "ss: dd: ss" dizesini döndüren küçük bir zamanlayıcı sınıfı:

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

Kullanımı:

# Start timer
my_timer = Timer()

# ... do something

# Get time string:
time_hhmmss = my_timer.get_time_hhmmss()
print("Time elapsed: %s" % time_hhmmss )

# ... use the timer again
my_timer.restart()

# ... do something

# Get time:
time_hhmmss = my_timer.get_time_hhmmss()

# ... etc

17

Python cProfile ve pstats modülleri, mevcut işlevlerin etrafına kod eklemek zorunda kalmadan belirli işlevlerde geçen süreyi ölçmek için büyük destek sunar.

Örneğin, bir python betiğiniz varsa timeFunctions.py:

import time

def 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()

Profil oluşturucuyu çalıştırmak ve dosya için istatistikler oluşturmak için şunları yapabilirsiniz:

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

Bunun yaptığı, timeFunctions.py içindeki tüm işlevleri profillemek ve timeStats.profile dosyasındaki istatistikleri toplamak için cProfile modülünü kullanmaktır. Mevcut modüle (timeFunctions.py) herhangi bir kod eklememiz gerekmediğini ve bunun herhangi bir modülle yapılabileceğini unutmayın.

İstatistik dosyasına sahip olduktan sonra pstats modülünü aşağıdaki gibi çalıştırabilirsiniz:

python -m pstats timeStats.profile

Bu, size birçok güzel işlevsellik veren etkileşimli istatistik tarayıcısını çalıştırır. Özel kullanım durumunuz için işlevinizin istatistiklerini kontrol edebilirsiniz. Örneğimizde her iki işlev için istatistikleri kontrol etmek bize aşağıdakileri gösterir:

Welcome to the profile statistics browser.
timeStats.profile% stats hello
<timestamp>    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
<timestamp>    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)

Kukla örnek pek bir şey yapmaz ancak size neler yapılabileceği hakkında bir fikir verir. Bu yaklaşımla ilgili en iyi yanı, bu sayıları almak ve açıkça profillemeye yardımcı olmak için mevcut kodumu düzenlemek zorunda olmamamdır.


Bütün bunlar iyi, ama AFAICT bu hala duvar saati değil CPU zamanını ölçer.
ShreevatsaR

1
Aslında bazı karışıklıklar var; cProfile varsayılan olarak duvar saati zamanına bakar. Cevabınızı iptal ettim.
ShreevatsaR

Bilginize: python -m pstats timeStats.profile ValueError: bad marshal data (unknown type code)Python sürümünüzü kontrol ederseniz çalıştırıyorsunuz. Koştuğumda anladım python3 -m cProfile...ve python -m pstats. Benim hatam ama bir an için beni aldı, bu yüzden paylaşmak istedim don't forget consistency. =)
JayRizzo

17

İşte zamanlama kodu için başka bir bağlam yöneticisi -

Kullanımı:

from benchmark import benchmark

with benchmark("Test 1+1"):
    1+1
=>
Test 1+1 : 1.41e-06 seconds

veya zaman değerine ihtiyacınız varsa

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

benchmark.py :

from timeit import default_timer as timer

class 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

Http://dabeaz.blogspot.fr/2010/02/context-manager-for-timing-benchmarks.html adresinden uyarlanmıştır.


17

Profil modülü kullanın. Çok detaylı bir profil verir.

import profile
profile.run('main()')

şöyle bir çıktı verir:

          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 <string>:1(<module>)
        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)

Çok bilgilendirici buldum.


1
Nedir main()? Basit bir kod örneği verebilirseniz daha yararlı olur.
not2qubit

15

Basit gibi (python 3):

from timeit import timeit

timeit(lambda: print("hello"))

Çıktı, tek bir yürütme için mikrosaniyedir :

2.430883963010274

Açıklama : timeit, anonim işlevi varsayılan olarak 1 milyon kez yürütür ve sonuç saniye olarak verilir . Bu nedenle, 1 tekli uygulamanın sonucu aynı miktarda ancak ortalama mikrosaniye cinsindendir .


İçin yavaş operasyonları daha düşük eklemek sayı yineleme ya da sonsuza bekliyor olabilir:

import time

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

Toplam yineleme sayısı için çıktı her zaman saniye cinsindendir :

1.5015795179999714

14

(Yalnızca Ipython ile) ortalama işlem süresini ölçmek için % timeit kullanabilirsiniz :

def foo():
    print "hello"

ve sonra:

%timeit foo()

sonuç şuna benzer:

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

4
% Timeit'e bayrak geçirmenin mümkün olduğunu belirtmek gerekir, örneğin -n, kodun kaç kez tekrarlanması gerektiğini belirtir.
raacer

11

Timeit'i kullanmanın bir yolu daha :

from timeit import timeit

def func():
    return 1 + 1

time = timeit(func, number=1)
print(time)

10

python3'te:

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

zarif ve kısa.


bu nedir? Hanım?
KIC

9

Daha sonra bir tür süper yanıt, ama belki birisine bir amaca hizmet eder. Süper temiz olduğunu düşünüyorum bunu yapmanın bir yoludur.

import time

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

timed(print, "Hello")

"Yazdır" ın Python 2.7'de değil, Python 3'te bir işlev olduğunu unutmayın. Ancak, başka herhangi bir işlevle çalışır. Şerefe!


Çok küçük zamanları nasıl yazdırabilirim? Her zaman 0.0 saniye alıyorum
Rowland Mtetezi

Bunu bir dekoratöre dönüştürebilirsiniz; bu benim için daha iyi görünüyor.
Daniel Moskovich

8

Timeit kullanabilirsiniz.

Python REPL kullanarak parametre alan naive_func test etmek için bir örnek:

>>> 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  

İşlevde herhangi bir parametre yoksa sarma işlevine ihtiyacınız yoktur.


1
A lambdadaha özlü olurdu:print(timeit.timeit(lambda: naive_func(1_000), number=1_000_000))
Ciro Santilli 法轮功 病毒 审查 六四 事件 法轮功

7

Ayrıca zamanı insan tarafından okunabilir zamana dönüştürebiliriz.

import time, datetime

start = 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 " % result

num_multi1(1000)

end = time.clock()
value = end - start
timestamp = datetime.datetime.fromtimestamp(value)
print timestamp.strftime('%Y-%m-%d %H:%M:%S')

6

Bunun için bir kütüphane yaptım, eğer bir fonksiyonu ölçmek istiyorsanız, bunu şu şekilde yapabilirsiniz


from pythonbenchmark import compare, measure
import time

a,b,c,d,e = 10,10,10,10,10
something = [a,b,c,d,e]

@measure
def myFunction(something):
    time.sleep(0.4)

@measure
def myOptimizedFunction(something):
    time.sleep(0.2)

myFunction(input)
myOptimizedFunction(input)

https://github.com/Karlheinzniebuhr/pythonbenchmark


6

Her işlev çağrısını yinelemeli olarak anlamak için şunları yapın:

%load_ext snakeviz
%%snakeviz

Sadece o alır 2 kod satırını bir de Jupyter notebook ve güzel bir interaktif diyagramı oluşturur. Örneğin:

resim açıklamasını buraya girin

İşte kod. Yine, 2 ile başlayan 2 satır, %snakeviz'i kullanmak için gereken ekstra kod satırlarıdır:

# !pip install snakeviz
%load_ext snakeviz
import glob
import hashlib

%%snakeviz

files = 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'i defterlerin dışında çalıştırmak da mümkün görünüyor. Snakeviz web sitesinde daha fazla bilgi .


2
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)

2

Bu benzersiz sınıf tabanlı yaklaşım, yazdırılabilir bir dize gösterimi, özelleştirilebilir yuvarlama ve bir dize veya kayan nokta olarak geçen süreye kolay erişim sunar. Python 3.7 ile geliştirilmiştir.

import datetime
import timeit


class 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)))

Kullanımı:

# Setup timer
>>> 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

1

Küçük kod parçacıklarının yürütme süresini ölçün.

Zaman birimi : kayan nokta olarak saniye cinsinden ölçülür

import timeit
t = timeit.Timer('li = list(map(lambda x:x*2,[1,2,3,4,5]))')
t.timeit()
t.repeat()
>[1.2934070999999676, 1.3335035000000062, 1.422568500000125]

Repeat () yöntemi, timeit () öğesini birden çok kez çağırmak ve bir sonuç listesi döndürmek için kolaylıktır.

repeat(repeat=3

Bu listeyle tüm zamanların ortalamasını alabiliriz.

Varsayılan olarak, timeit () zamanlama sırasında çöp toplamayı geçici olarak kapatır. time.Timer () bu sorunu çözer.

Artıları:

timeit.Timer () bağımsız zamanlamaları daha karşılaştırılabilir hale getirir. Gc, ölçülen işlevin performansının önemli bir bileşeni olabilir. Öyleyse, gc (çöp toplayıcı) kurulum dizesindeki ilk ifade olarak yeniden etkinleştirilebilir. Örneğin:

timeit.Timer('li = list(map(lambda x:x*2,[1,2,3,4,5]))',setup='gc.enable()')

Kaynak Python Dokümanları !


1

İşlevleri uygun şekilde zamanlamak istiyorsanız, basit bir dekoratör kullanabilirsiniz:

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        original_return_val = func(*args, **kwargs)
        end = time.time()
        print("time elapsed in ", func.__name__, ": ", end - start, sep='')
        return original_return_val

    return wrapper

Bu şekilde zamanlamak istediğiniz bir işlevde kullanabilirsiniz:

@timing_decorator
def function_to_time():
    time.sleep(1)

Daha sonra aradığınızda function_to_time, ne kadar sürdüğünü ve zamanlanan işlevin adını yazdıracaktır.


1

flake8'in E731'e göre lambda kullanımına ilişkin uyarıda bulunduğu gibi, https://stackoverflow.com/a/30024601/5095636 tarafından verilen bağlam yönetimi çözümüne dayanarak, lambda ücretsiz sürümünün altında :

from contextlib import contextmanager
from timeit import default_timer

@contextmanager
def elapsed_timer():
    start_time = default_timer()

    class _Timer():
      start = start_time
      end = default_timer()
      duration = end - start

    yield _Timer

    end_time = default_timer()
    _Timer.end = end_time
    _Timer.duration = end_time - start_time

Ölçek:

from time import sleep

with elapsed_timer() as t:
    print("start:", t.start)
    sleep(1)
    print("end:", t.end)

t.start
t.end
t.duration

1

İşte genel bir yardımcı program olarak kullandığım oldukça iyi belgelenmiş ve tam tip ipucu dekoratör:

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

Örnek kullanım:

from timer import timer


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


print(takes_long(10**8))

Çıktı:

takes_long: 4.942629056s
True

Doctests ile kontrol edilebilir:

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

Ve tür ile ipuçları:

$ mypy timer.py

1
Bu çok havalı, paylaştığın için teşekkürler. Yazma kütüphanesi veya yerel olmayan anahtar kelime ile karşılaşmadım - eğlenceli yeni şeyler bulmak için. Sorun bu kafamı sarma yaşıyorum: Callable[[AnyF], AnyF]. Bunun anlamı ne?
Danny

1
Ben tip takma tanımladığınız Üstüne üstlük @Danny AnyFanlamında Callable[..., Any], yani AnyFher tür argümanlar ve dönüş şey herhangi bir miktar alabilir bir işlevdir. Böylece Callable[[AnyF], AnyF]genişleyecekti Callable[[Callable[..., Any]], Callable[..., Any]]. Bu, timeraka tam tipinin dönüş değerinin türüdür decorator. Herhangi bir işlevi tek argüman olarak alan ve her türlü işlevi döndüren bir işlevdir.
ruohola

1
Açıklama için teşekkürler! Hala kafamı dekoratörlerin içine tamamen sarmaya çalışıyorum. Bu çok yardımcı oldu!
Danny

0

Aklıma gelen tek yol kullanmak time.time().

import time
start = time.time()
sleep(5) #just to give it some delay to show it working
finish = time.time()
elapsed = finish - start
print(elapsed)

Umarım yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.