Matlab'ın tik ve toc işlevlerinin Python eşdeğeri nedir ?
tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()
o zaman print toc-tic
.
Matlab'ın tik ve toc işlevlerinin Python eşdeğeri nedir ?
tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()
o zaman print toc-tic
.
Yanıtlar:
timeit
ThiefMaster'ın bahsettiğinin dışında, bunu yapmanın basit bir yolu (içe aktardıktan sonra time
):
t = time.time()
# do stuff
elapsed = time.time() - t
Kullanmayı sevdiğim yardımcı bir sınıfım var:
class Timer(object):
def __init__(self, name=None):
self.name = name
def __enter__(self):
self.tstart = time.time()
def __exit__(self, type, value, traceback):
if self.name:
print('[%s]' % self.name,)
print('Elapsed: %s' % (time.time() - self.tstart))
Bir bağlam yöneticisi olarak kullanılabilir:
with Timer('foo_stuff'):
# do some foo
# do some stuff
Bazen bu tekniği daha uygun buluyorum timeit
- hepsi ölçmek istediğiniz şeye bağlı.
time
sonsuza dek programların çalışma zamanlarını ölçmek için unix komutunu kullanıyorlar ve bu yöntem bunu Python kodu içinde çoğaltır. İş için doğru araç olduğu sürece bunda yanlış bir şey görmüyorum. timeit
her zaman böyle değildir ve profil oluşturucu çoğu ihtiyaç için çok daha ağır bir çözümdür
print 'Elapsed: %.2f seconds % (time.time() - self.tstart)'
. % .2f olmadan anlamak zor. Harika fikir için teşekkürler.
elapsed = t - time.time()
yerine istediğini düşünüyorum elapsed = time.time() - t
. İkincisi geçen süre negatif olacaktır. Bu değişikliği bir düzenleme olarak önerdim.
elapsed = time.time() - t
her zaman pozitif bir değer veren formdur.
Matlab'dan python'a geçerken de aynı soruyu sormuştum. Bu iş parçacığının yardımıyla Matlab'ın ve fonksiyonlarının tam bir benzerini oluşturabildim . Aşağıdaki kodu komut dosyanızın en üstüne eklemeniz yeterlidir.tic()
toc()
import time
def TicTocGenerator():
# Generator that returns time differences
ti = 0 # initial time
tf = time.time() # final time
while True:
ti = tf
tf = time.time()
yield tf-ti # returns the time difference
TicToc = TicTocGenerator() # create an instance of the TicTocGen generator
# This will be the main function through which we define both tic() and toc()
def toc(tempBool=True):
# Prints the time difference yielded by generator instance TicToc
tempTimeInterval = next(TicToc)
if tempBool:
print( "Elapsed time: %f seconds.\n" %tempTimeInterval )
def tic():
# Records a time in TicToc, marks the beginning of a time interval
toc(False)
Bu kadar! Şimdi tamamen kullanıma hazır tic()
ve toc()
sadece Matlabda olarak. Örneğin
tic()
time.sleep(5)
toc() # returns "Elapsed time: 5.00 seconds."
Aslında bu, yerleşik Matlab işlevlerinden daha çok yönlüdür. Burada, TicTocGenerator
birden çok işlemi takip etmek için veya sadece işleri farklı şekilde zamanlamak için başka bir örnek oluşturabilirsiniz . Örneğin, bir komut dosyasını zamanlarken, artık komut dosyasının her parçasını ve tüm komut dosyasını ayrı ayrı ölçebiliriz. (Somut bir örnek vereceğim)
TicToc2 = TicTocGenerator() # create another instance of the TicTocGen generator
def toc2(tempBool=True):
# Prints the time difference yielded by generator instance TicToc2
tempTimeInterval = next(TicToc2)
if tempBool:
print( "Elapsed time 2: %f seconds.\n" %tempTimeInterval )
def tic2():
# Records a time in TicToc2, marks the beginning of a time interval
toc2(False)
Şimdi iki ayrı şeyi zamanlayabilmelisiniz: Aşağıdaki örnekte, toplam komut dosyası ve bir komut dosyasının bölümlerini ayrı ayrı ölçüyoruz.
tic()
time.sleep(5)
tic2()
time.sleep(3)
toc2() # returns "Elapsed time 2: 5.00 seconds."
toc() # returns "Elapsed time: 8.00 seconds."
Aslında tic()
her seferinde kullanmanıza bile gerek yok . Zamanlamak istediğiniz bir dizi komutunuz varsa, yazabilirsiniz
tic()
time.sleep(1)
toc() # returns "Elapsed time: 1.00 seconds."
time.sleep(2)
toc() # returns "Elapsed time: 2.00 seconds."
time.sleep(3)
toc() # returns "Elapsed time: 3.00 seconds."
# and so on...
Umarım bu yardımcı olur.
Tic ve toc'un mutlak en iyi analoğu, onları python'da basitçe tanımlamak olacaktır.
def tic():
#Homemade version of matlab tic and toc functions
import time
global startTime_for_tictoc
startTime_for_tictoc = time.time()
def toc():
import time
if 'startTime_for_tictoc' in globals():
print "Elapsed time is " + str(time.time() - startTime_for_tictoc) + " seconds."
else:
print "Toc: start time not set"
O zaman bunları şu şekilde kullanabilirsiniz:
tic()
# do stuff
toc()
tic
ve iç içe kullanım durumunda bu doğru davranmayacaktır toc
. Biraz daha karmaşıklık gerekli olacaktır.
import time
, potansiyel olarak biraz zaman alabileceğinden, her iki işlevin dışını da kaldırırım .
tic
onu itip çıkmasına izin verin toc
.
timeit.default_timer()
daha iyi olduğunu time.time()
çünkü time.clock()
OS bağlı olarak daha uygun olabilir
Genellikle ipython en %time
, %timeit
, %prun
ve %lprun
(bir eğer line_profiler
yüklü) oldukça iyi benim profilleme ihtiyaçlarını karşılamak. Bununla birlikte, tic-toc
etkileşimli olarak, yani bir GUI'de kullanıcının fare hareketi tarafından yönlendirilen hesaplamaların profilini çıkarmaya çalıştığımda, benzer işlevsellik için bir kullanım durumu ortaya çıktı. Ben spam gibi hissettim tic
ler ve toc
etkileşimli test darboğazları ortaya çıkarmak için hızlı yolu olacağını ise kaynaklarda s. Eli Bendersky'nin Timer
sınıfıyla gittim , ancak kodumun girintisini değiştirmemi gerektirdiğinden, bazı editörlerde rahatsız edici olabilecek ve sürüm kontrol sistemini karıştırdığı için tam olarak mutlu değildim. Dahası, farklı işlevlerdeki noktalar arasındaki zamanı ölçme ihtiyacı olabilir ve bu,with
Beyan. Pek çok Python zekasını denedikten sonra, işte bulduğum basit çözüm en iyi sonucu verdi:
from time import time
_tstart_stack = []
def tic():
_tstart_stack.append(time())
def toc(fmt="Elapsed: %s s"):
print fmt % (time() - _tstart_stack.pop())
Bu, bir yığındaki başlangıç zamanlarını iterek çalıştığından, birden çok düzeydeki tic
s ve toc
s için doğru şekilde çalışacaktır . Ayrıca toc
, Eli'nin Timer
sınıfı hakkında sevdiğim ek bilgileri görüntülemek için ifadenin biçim dizesini değiştirmeye izin veriyor .
Bazı nedenlerden dolayı saf bir Python uygulamasının ek yüküyle ilgileniyordum, bu yüzden bir C genişletme modülünü de test ettim:
#include <Python.h>
#include <mach/mach_time.h>
#define MAXDEPTH 100
uint64_t start[MAXDEPTH];
int lvl=0;
static PyObject* tic(PyObject *self, PyObject *args) {
start[lvl++] = mach_absolute_time();
Py_RETURN_NONE;
}
static PyObject* toc(PyObject *self, PyObject *args) {
return PyFloat_FromDouble(
(double)(mach_absolute_time() - start[--lvl]) / 1000000000L);
}
static PyObject* res(PyObject *self, PyObject *args) {
return tic(NULL, NULL), toc(NULL, NULL);
}
static PyMethodDef methods[] = {
{"tic", tic, METH_NOARGS, "Start timer"},
{"toc", toc, METH_NOARGS, "Stop timer"},
{"res", res, METH_NOARGS, "Test timer resolution"},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC
inittictoc(void) {
Py_InitModule("tictoc", methods);
}
Bu, MacOSX içindir ve lvl
kısalık açısından sınırların dışında olup olmadığını kontrol etmek için kodu atladım. İken tictoc.res()
verim sistemimde yaklaşık 50 nanosaniye çözünürlük, ben (ipython gelen kullanıldığında çok daha ve) Herhangi bir Python deyimini ölçme titreşim mikrosaniye aralığında kolayca tespit ettik. Bu noktada, Python uygulamasının ek yükü ihmal edilebilir hale gelir, böylece C uygulamasıyla aynı güvenle kullanılabilir.
tic-toc
-Yaklaşımının kullanışlılığının, yürütmesi 10 mikrosaniyeden fazla süren kod bloklarıyla sınırlı olduğunu buldum . Bunun altında, timeit
güvenilir bir ölçüm elde etmek için in gibi ortalama stratejileri gereklidir.
tic
Ve toc
ile kullanabilirsiniz ttictoc
. İle yükleyin
pip install ttictoc
Ve bunları komut dosyanıza aşağıdaki gibi içe aktarın
from ttictoc import tic,toc
tic()
# Some code
print(toc())
Matlab'ın yaptığı gibi iç içe geçmiş tic tocs elde etmek için bir modül [tictoc.py] oluşturdum.
from time import time
tics = []
def tic():
tics.append(time())
def toc():
if len(tics)==0:
return None
else:
return time()-tics.pop()
Ve şu şekilde çalışır:
from tictoc import tic, toc
# This keeps track of the whole process
tic()
# Timing a small portion of code (maybe a loop)
tic()
# -- Nested code here --
# End
toc() # This returns the elapse time (in seconds) since the last invocation of tic()
toc() # This does the same for the first tic()
Umut ediyorum bu yardım eder.
timeit
Modüle bir göz atın . Gerçekten eşdeğer değil ama zamanını almak istediğiniz kod bir işlevin içindeyse, onu kolayca kullanabilirsiniz.
timeit
kıyaslamalar için en iyisidir. Tek bir işlev olmak zorunda bile değil, sürekli olarak karmaşık ifadeler iletebilirsiniz.
pip install easy-tictoc
Kodda:
from tictoc import tic, toc
tic()
#Some code
toc()
Feragatname: Bu kütüphanenin yazarıyım.
Bu aynı zamanda bir sarmalayıcı kullanılarak da yapılabilir. Zamanı tutmanın çok genel bir yolu.
Bu örnek koddaki sarmalayıcı, herhangi bir işlevi sarar ve işlevi yürütmek için gereken süreyi yazdırır:
def timethis(f):
import time
def wrapped(*args, **kwargs):
start = time.time()
r = f(*args, **kwargs)
print "Executing {0} took {1} seconds".format(f.func_name, time.time()-start)
return r
return wrapped
@timethis
def thistakestime():
for x in range(10000000):
pass
thistakestime()
@Eli Bendersky'nin cevabını , zamanlamayı yapmak için ctor __init__()
ve dtor'u kullanmak için biraz değiştirdim __del__()
, böylece orijinal kodu girmeden daha rahat bir şekilde kullanılabilir:
class Timer(object):
def __init__(self, name=None):
self.name = name
self.tstart = time.time()
def __del__(self):
if self.name:
print '%s elapsed: %.2fs' % (self.name, time.time() - self.tstart)
else:
print 'Elapsed: %.2fs' % (time.time() - self.tstart)
Kullanmak için, Timer'ı ("blahblah") bazı yerel kapsamların başına koyun. Geçen süre kapsamın sonunda yazdırılacaktır:
for i in xrange(5):
timer = Timer("eigh()")
x = numpy.random.random((4000,4000));
x = (x+x.T)/2
numpy.linalg.eigh(x)
print i+1
timer = None
Çıktı:
1
eigh() elapsed: 10.13s
2
eigh() elapsed: 9.74s
3
eigh() elapsed: 10.70s
4
eigh() elapsed: 10.25s
5
eigh() elapsed: 11.28s
timer
, for
döngüden sonra başka bir kod izlerse, son çağrıdan sonra silinmemesidir . Son zamanlayıcı değerini elde etmek timer
için for
döngüden sonra silinmeli veya üzerine yazılmalıdır , örn timer = None
.
Eli'nin Python 3'e cevabını güncelleme :
class Timer(object):
def __init__(self, name=None, filename=None):
self.name = name
self.filename = filename
def __enter__(self):
self.tstart = time.time()
def __exit__(self, type, value, traceback):
message = 'Elapsed: %.2f seconds' % (time.time() - self.tstart)
if self.name:
message = '[%s] ' % self.name + message
print(message)
if self.filename:
with open(self.filename,'a') as file:
print(str(datetime.datetime.now())+": ",message,file=file)
Eli'ninki gibi, bir bağlam yöneticisi olarak kullanılabilir:
import time
with Timer('Count'):
for i in range(0,10_000_000):
pass
Çıktı:
[Count] Elapsed: 0.27 seconds
Ayrıca, Can'ın önerdiği şekilde bildirilen zaman birimlerini (saniye) yazdırmak ve basamak sayısını kırpmak ve ayrıca bir günlük dosyasına ekleme seçeneği ile güncelledim. Günlük özelliğini kullanmak için tarih saatini içe aktarmanız gerekir:
import time
import datetime
with Timer('Count', 'log.txt'):
for i in range(0,10_000_000):
pass
Stefan ve antonimmo'nun yanıtlarına dayanarak,
def Tictoc():
start_stack = []
start_named = {}
def tic(name=None):
if name is None:
start_stack.append(time())
else:
start_named[name] = time()
def toc(name=None):
if name is None:
start = start_stack.pop()
else:
start = start_named.pop(name)
elapsed = time() - start
return elapsed
return tic, toc
bir utils.py
modülde ve bunu bir
from utils import Tictoc
tic, toc = Tictoc()
Bu yoldan
tic()
, toc()
ve yuva onları Matlabda gibitic(1)
, toc(1)
veya tic('very-important-block')
, toc('very-important-block')
ve farklı isimlerle zamanlayıcılar engel olmaz(burada toc geçen süreyi yazdırmaz, ancak onu döndürür.)
tic = time.time()
vetoc = time.time()
ardındanprint toc-tic, 'sec Elapsed'
, aşağıda insanların söylediği gibi, yinetimeit
de daha sağlamdır.