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 timeit
yang 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.
time
perintah 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. timeit
tidak 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 TicTocGenerator
untuk 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()
tic
dan toc
, yang didukung Matlab. Diperlukan sedikit lebih banyak kecanggihan.
import time
luar kedua fungsi, karena ini bisa memakan waktu cukup lama.
tic
mendorong ke sana dan keluar toc
darinya.
timeit.default_timer()
lebih baik daripada time.time()
karena time.clock()
mungkin lebih sesuai tergantung pada OS
Biasanya, IPython ini %time
, %timeit
, %prun
dan %lprun
(jika telah line_profiler
diinstal) memenuhi kebutuhan profil saya cukup baik. Namun, kasus penggunaan untuk tic-toc
fungsionalitas -seperti muncul ketika saya mencoba membuat profil kalkulasi yang didorong secara interaktif, yaitu, oleh gerakan mouse pengguna di GUI. Saya merasa ingin melakukan spamming tic
dantoc
s di sumber sementara pengujian interaktif akan menjadi cara tercepat untuk mengungkap kemacetan. Saya mengikuti Timer
kelas 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 denganwith
pernyataan. 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 tic
s dan toc
s. Ini juga memungkinkan seseorang untuk mengubah string format toc
pernyataan untuk menampilkan informasi tambahan, yang saya suka tentang Timer
kelas 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 lvl
luar 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 timeit
untuk mendapatkan ukuran yang tepat.
Anda dapat menggunakan tic
dan toc
dari 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 timeit
modulnya. Ini tidak benar-benar setara tetapi jika kode yang Anda inginkan waktu ada di dalam fungsi, Anda dapat dengan mudah menggunakannya.
timeit
yang 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
timer
tidak dihapus setelah panggilan terakhir, jika kode lain mengikuti setelah for
loop. Untuk mendapatkan nilai timer terakhir, seseorang harus menghapus atau menimpa loop timer
setelahnya 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.py
modul, 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,timeit
lebih kuat.