Apa persamaan Python dari fungsi tic dan toc Matlab ?
tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()lalu print toc-tic.
Apa persamaan Python dari fungsi tic dan toc Matlab ?
tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()lalu print toc-tic.
Jawaban:
Selain timeityang disebutkan ThiefMaster, cara sederhana untuk melakukannya adalah (setelah mengimpor time):
t = time.time()
# do stuff
elapsed = time.time() - t
Saya memiliki kelas helper yang saya suka gunakan:
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))
Ini dapat digunakan sebagai manajer konteks:
with Timer('foo_stuff'):
# do some foo
# do some stuff
Kadang-kadang saya merasa teknik ini lebih nyaman daripada timeit- semuanya tergantung pada apa yang ingin Anda ukur.
timeperintah unix untuk mengukur runtime program untuk selamanya, dan metode ini mereplikasi ini di dalam kode Python. Saya tidak melihat ada yang salah dengan itu, selama itu alat yang tepat untuk pekerjaan itu. timeittidak selalu begitu, dan profiler adalah solusi kelas berat yang jauh lebih berat untuk sebagian besar kebutuhan
print 'Elapsed: %.2f seconds % (time.time() - self.tstart)'. Sulit untuk memahami tanpa% .2f. Terima kasih untuk ide yang bagus.
elapsed = t - time.time(), bukan elapsed = time.time() - t. Yang terakhir berlalu akan menjadi negatif. Saya menyarankan perubahan ini sebagai edit.
elapsed = time.time() - t, bentuk itulah yang selalu menghasilkan nilai positif.
Saya memiliki pertanyaan yang sama ketika saya bermigrasi ke python dari Matlab. Dengan bantuan utas ini saya dapat membuat analog yang tepat dari Matlab tic()dan toc()fungsi. Cukup masukkan kode berikut di bagian atas skrip Anda.
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)
Itu dia! Sekarang kami siap untuk menggunakan sepenuhnya tic()dan toc()seperti di Matlab. Sebagai contoh
tic()
time.sleep(5)
toc() # returns "Elapsed time: 5.00 seconds."
Sebenarnya, ini lebih serbaguna daripada fungsi Matlab bawaan. Di sini, Anda dapat membuat contoh lain TicTocGeneratoruntuk melacak beberapa operasi, atau hanya mengatur waktu secara berbeda. Misalnya, saat mengatur waktu skrip, sekarang kita dapat menentukan waktu setiap bagian skrip secara terpisah, serta seluruh skrip. (Saya akan memberikan contoh konkret)
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)
Sekarang Anda seharusnya dapat mengatur waktu dua hal yang terpisah: Dalam contoh berikut, kita menghitung waktu total skrip dan bagian skrip secara terpisah.
tic()
time.sleep(5)
tic2()
time.sleep(3)
toc2() # returns "Elapsed time 2: 5.00 seconds."
toc() # returns "Elapsed time: 8.00 seconds."
Sebenarnya, Anda bahkan tidak perlu menggunakannya tic() setiap saat. Jika Anda memiliki serangkaian perintah yang Anda ingin waktu, maka Anda dapat menulis
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...
Saya harap ini membantu.
Analog terbaik mutlak dari tic dan toc adalah dengan mendefinisikannya dengan python.
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"
Kemudian Anda dapat menggunakannya sebagai:
tic()
# do stuff
toc()
ticdan toc, yang didukung Matlab. Diperlukan sedikit lebih banyak kecanggihan.
import timeluar kedua fungsi, karena ini bisa memakan waktu cukup lama.
ticmendorong ke sana dan keluar tocdarinya.
timeit.default_timer()lebih baik daripada time.time()karena time.clock()mungkin lebih sesuai tergantung pada OS
Biasanya, IPython ini %time, %timeit, %prundan %lprun(jika telah line_profilerdiinstal) memenuhi kebutuhan profil saya cukup baik. Namun, kasus penggunaan untuk tic-tocfungsionalitas -seperti muncul ketika saya mencoba membuat profil kalkulasi yang didorong secara interaktif, yaitu, oleh gerakan mouse pengguna di GUI. Saya merasa ingin melakukan spamming ticdantoc s di sumber sementara pengujian interaktif akan menjadi cara tercepat untuk mengungkap kemacetan. Saya mengikuti Timerkelas Eli Bendersky , tetapi tidak sepenuhnya senang, karena itu mengharuskan saya untuk mengubah lekukan kode saya, yang dapat merepotkan di beberapa editor dan membingungkan sistem kontrol versi. Selain itu, mungkin ada kebutuhan untuk mengukur waktu antar titik dalam fungsi yang berbeda, yang tidak akan berfungsi denganwithpernyataan. Setelah mencoba banyak kecerdasan Python, berikut adalah solusi sederhana yang menurut saya paling berhasil:
from time import time
_tstart_stack = []
def tic():
_tstart_stack.append(time())
def toc(fmt="Elapsed: %s s"):
print fmt % (time() - _tstart_stack.pop())
Karena ini bekerja dengan mendorong waktu mulai pada tumpukan, ini akan bekerja dengan benar untuk beberapa level tics dan tocs. Ini juga memungkinkan seseorang untuk mengubah string format tocpernyataan untuk menampilkan informasi tambahan, yang saya suka tentang Timerkelas Eli .
Untuk beberapa alasan saya khawatir dengan overhead dari implementasi Python murni, jadi saya menguji modul ekstensi C juga:
#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);
}
Ini untuk MacOSX, dan saya telah menghilangkan kode untuk memeriksa apakah di lvlluar batas untuk singkatnya. Sementara tictoc.res()menghasilkan resolusi sekitar 50 nanodetik di sistem saya, saya menemukan bahwa jitter dalam mengukur pernyataan Python apa pun dengan mudah berada dalam kisaran mikrodetik (dan lebih banyak lagi bila digunakan dari IPython). Pada titik ini, overhead implementasi Python menjadi dapat diabaikan, sehingga dapat digunakan dengan tingkat kepercayaan yang sama seperti implementasi C.
Saya menemukan bahwa kegunaan tic-toc-approach secara praktis terbatas pada blok kode yang membutuhkan lebih dari 10 mikrodetik untuk dieksekusi. Di bawah itu, diperlukan strategi rata-rata seperti in timeituntuk mendapatkan ukuran yang tepat.
Anda dapat menggunakan ticdan tocdari ttictoc. Instal dengan
pip install ttictoc
Dan impor saja di skrip Anda sebagai berikut
from ttictoc import tic,toc
tic()
# Some code
print(toc())
Saya baru saja membuat modul [tictoc.py] untuk mencapai tic tocs bersarang, yang dilakukan oleh Matlab.
from time import time
tics = []
def tic():
tics.append(time())
def toc():
if len(tics)==0:
return None
else:
return time()-tics.pop()
Dan cara kerjanya seperti ini:
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()
Saya harap ini membantu.
Lihat timeitmodulnya. Ini tidak benar-benar setara tetapi jika kode yang Anda inginkan waktu ada di dalam fungsi, Anda dapat dengan mudah menggunakannya.
timeityang terbaik untuk tolok ukur. Ia bahkan tidak harus menjadi satu fungsi, Anda dapat memberikan pernyataan yang sangat rumit.
pip install easy-tictoc
Dalam kode:
from tictoc import tic, toc
tic()
#Some code
toc()
Penafian: Saya adalah pembuat perpustakaan ini.
Ini juga bisa dilakukan dengan menggunakan pembungkus. Cara yang sangat umum untuk menghitung waktu.
Wrapper dalam kode contoh ini membungkus fungsi apa pun dan mencetak jumlah waktu yang diperlukan untuk menjalankan fungsi tersebut:
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()
Saya mengubah jawaban @Eli Bendersky sedikit untuk menggunakan ctor __init__()dan dtor __del__()untuk melakukan pengaturan waktu, sehingga dapat digunakan dengan lebih nyaman tanpa memasukkan kode aslinya:
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)
Untuk menggunakannya, letakkan Timer ("bla bla") di awal beberapa lingkup lokal. Waktu yang berlalu akan dicetak di akhir ruang lingkup:
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
Ini mencetak:
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
timertidak dihapus setelah panggilan terakhir, jika kode lain mengikuti setelah forloop. Untuk mendapatkan nilai timer terakhir, seseorang harus menghapus atau menimpa loop timersetelahnya for, misalnya via timer = None.
Memperbarui jawaban Eli untuk Python 3:
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)
Sama seperti Eli, ini dapat digunakan sebagai manajer konteks:
import time
with Timer('Count'):
for i in range(0,10_000_000):
pass
Keluaran:
[Count] Elapsed: 0.27 seconds
Saya juga telah memperbaruinya untuk mencetak satuan waktu yang dilaporkan (detik) dan memangkas jumlah digit seperti yang disarankan oleh Can, dan dengan opsi untuk juga menambahkan ke file log. Anda harus mengimpor datetime untuk menggunakan fitur logging:
import time
import datetime
with Timer('Count', 'log.txt'):
for i in range(0,10_000_000):
pass
Berdasarkan jawaban Stefan dan antonimmo, saya akhirnya meletakkan
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
dalam utils.pymodul, dan saya menggunakannya dengan file
from utils import Tictoc
tic, toc = Tictoc()
Cara ini
tic(), toc()dan menyarangkannya seperti di Matlabtic(1), toc(1)atau tic('very-important-block'), toc('very-important-block')dan timer dengan nama yang berbeda tidak akan mengganggu(di sini toc tidak mencetak waktu yang telah berlalu, tetapi mengembalikannya.)
tic = time.time()dantoc = time.time(), seperti yangprint toc-tic, 'sec Elapsed'dikatakan orang di bawah ini,timeitlebih kuat.