माटलैब के टिक और टॉक कार्यों के बराबर पायथन क्या है?


112

माटलैब के टिक और टॉक कार्यों के बराबर पायथन क्या है ?


7
यदि आप वास्तव में प्रत्यक्ष समकक्ष चाहते हैं , तो बस कॉल करें tic = time.time()और toc = time.time(), print toc-tic, 'sec Elapsed'जैसा कि लोगों ने नीचे कहा है, हालांकि, timeitअधिक मजबूत है।
जो किंग्सटन

मुझे लगता है कि timeit.default_timer () के साथ संयोजन के रूप में @ जोकिंगटन के दृष्टिकोण का उपयोग करके बेहतर परिणाम प्राप्त होते हैं, उदाहरण के लिए इस तरह: tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()फिर print toc-tic
छोटू

1
लाइब्रेरी पाइटिक्टोक सबसे अधिक प्रतीत होता है, सिंटैक्स नीचे ttictoc की तुलना में थोड़ा अधिक नट है। pypi.org/project/pytictoc
फ्लोरियन एचएच

जवाबों:


172

इसके अलावा timeit, थिएम्पैस्टर ने जो उल्लेख किया है, उसे करने का एक सरल तरीका सिर्फ (आयात करने के बाद time) है:

t = time.time()
# do stuff
elapsed = time.time() - t

मेरे पास एक सहायक वर्ग है जो मुझे उपयोग करना पसंद है:

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

इसका उपयोग संदर्भ प्रबंधक के रूप में किया जा सकता है:

with Timer('foo_stuff'):
   # do some foo
   # do some stuff

कभी-कभी मुझे यह तकनीक अधिक सुविधाजनक लगती है timeit- यह सब इस बात पर निर्भर करता है कि आप क्या मापना चाहते हैं।


25
@eat: मैं सम्मान से असहमत हूं। लोग यूनिक्स timeकमांड का उपयोग हमेशा के लिए कार्यक्रमों के रनटाइम्स को मापने के लिए कर रहे हैं, और यह विधि इसे पायथन कोड के अंदर दोहराती है। मैं इसके साथ कुछ भी गलत नहीं देखता, जब तक कि यह काम का सही उपकरण है। timeitहमेशा ऐसा नहीं होता है, और अधिकांश जरूरतों के लिए एक प्रोफाइलर एक बहुत अधिक वजनदार समाधान होता है
एली बेंडरस्की

4
अंतिम पंक्ति के लिए मैं सुझाव दूंगा print 'Elapsed: %.2f seconds % (time.time() - self.tstart)'। द% खकर बबबब द% वख करन without2 without महान विचार के लिए धन्यवाद।
कैन क्वालालू

4
यह पहली नज़र में बहुत सुविधाजनक लग रहा है, लेकिन व्यवहार में कोड ब्लॉक को समय-समय पर एक इंडेंट करने की आवश्यकता होती है, जो कोड ब्लॉक की लंबाई और पसंद के संपादक के आधार पर काफी असुविधाजनक हो सकता है। फिर भी एक सुरुचिपूर्ण समाधान, जो नेस्टेड उपयोग के मामले में सही ढंग से व्यवहार करता है।
स्टीफन

1
मुझे लगता है कि आप के elapsed = t - time.time()बजाय चाहते हैं elapsed = time.time() - t। उत्तरार्द्ध में नकारात्मक होगा। मैंने इस बदलाव को एक संपादन के रूप में सुझाया है।
rysqui

3
@rysqui - क्या वर्तमान समय हमेशा पिछली बार की तुलना में एक बड़ी संख्या नहीं है ? मुझे लगता है कि elapsed = time.time() - tयह वह रूप है जो हमेशा एक सकारात्मक मूल्य देता है।
स्कॉट स्मिथ

32

मेरे पास यही सवाल था जब मैं मतलाब से अजगर के पास चला गया। इस धागे की मदद से मैं मतलाब और कार्यों के एक सटीक एनालॉग का निर्माण करने में सक्षम था । बस अपनी स्क्रिप्ट के शीर्ष पर निम्न कोड डालें।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)

बस! अब हम पूरी तरह से उपयोग करने के लिए तैयार हैं tic()और toc()ठीक उसी तरह जैसे कि मतलाब में। उदाहरण के लिए

tic()

time.sleep(5)

toc() # returns "Elapsed time: 5.00 seconds."

दरअसल, यह बिल्ट-इन मटलब कार्यों की तुलना में अधिक बहुमुखी है। यहां, आप TicTocGeneratorकई कार्यों का ट्रैक रखने के लिए, या बस कुछ समय के लिए चीजों को अलग तरीके से बना सकते हैं। उदाहरण के लिए, किसी स्क्रिप्ट को टाइम करते समय, अब हम स्क्रिप्ट के प्रत्येक टुकड़े को अलग-अलग समय के साथ-साथ पूरी स्क्रिप्ट को टाइम कर सकते हैं। (मैं एक ठोस उदाहरण प्रदान करूंगा)

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)

अब आपको दो अलग-अलग चीजों को करने में सक्षम होना चाहिए: निम्नलिखित उदाहरण में, हम कुल स्क्रिप्ट और स्क्रिप्ट के कुछ हिस्सों को अलग-अलग समय देते हैं।

tic()

time.sleep(5)

tic2()

time.sleep(3)

toc2() # returns "Elapsed time 2: 5.00 seconds."

toc() # returns "Elapsed time: 8.00 seconds."

दरअसल, आपको tic()हर बार इस्तेमाल करने की भी जरूरत नहीं है । यदि आपके पास आदेशों की एक श्रृंखला है जिसे आप समय देना चाहते हैं, तो आप लिख सकते हैं

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

मुझे उम्मीद है कि यह मददगार है।


22

टिक और टीओसी का पूर्ण सर्वोत्तम एनालॉग केवल उन्हें अजगर में परिभाषित करना होगा।

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"

तो आप उन्हें इस रूप में उपयोग कर सकते हैं:

tic()
# do stuff
toc()

6
यह नेस्टेड के उपयोग के मामले में सही ढंग से व्यवहार नहीं करेगा ticऔर toc, जो कि मैटलैब समर्थन करता है। थोड़ा और परिष्कार की आवश्यकता होगी।
स्टीफन

2
मैंने अपने स्वयं के कोड में इसी तरह के कार्यों को लागू किया है जब मुझे कुछ बुनियादी समय की आवश्यकता थी। लेकिन मैं import timeदोनों कार्यों के बाहर निकाल दूंगा, क्योंकि यह संभावित रूप से कुछ समय ले सकता है।
बास स्विंकल्स

यदि आप इस तकनीक का उपयोग करने पर जोर देते हैं, और आपको इसे नेस्टेड टिक / टीओसी को संभालने की आवश्यकता है, तो वैश्विक सूची बनाएं और इसे ticधक्का दें और इससे tocपॉप करें।
अहमद फ़सीह

1
इसके अलावा मैं कहीं और पढ़ता हूं जो इससे timeit.default_timer()बेहतर है time.time()क्योंकि time.clock()यह OS पर निर्भर हो सकता है
Miguel

@AhmedFasih यही मेरा जवाब है, हालांकि अधिक चीजों में सुधार किया जा सकता है।
एंटोनिमो

15

आमतौर पर, IPython का %time, %timeit, %prunऔर %lprun(यदि कोई है line_profilerस्थापित) मेरी रूपरेखा की जरूरत काफी अच्छी तरह से पूरा करते हैं। हालाँकि, tic-tocजब मैं एक GUI में उपयोगकर्ता के माउस गति द्वारा, यानी, अंतःक्रियात्मक रूप से संचालित होने वाली गणना की कोशिश करने के लिए -इस तरह की कार्यक्षमता के लिए उपयोग मामला उत्पन्न हुआ। मुझे ऐसा महसूस हुआ कि सूत्रों का परीक्षण करते समय ticएस और tocएस को स्पैमिंग करना, बाधाओं को प्रकट करने का सबसे तेज़ तरीका होगा। मैं एली बेंडरस्की की Timerकक्षा के साथ गया था, लेकिन पूरी तरह से खुश नहीं था, क्योंकि इससे मुझे अपने कोड के इंडेंटेशन को बदलने की आवश्यकता हुई, जो कुछ संपादकों में असुविधाजनक हो सकता है और संस्करण नियंत्रण प्रणाली को भ्रमित करता है। इसके अलावा, विभिन्न कार्यों में बिंदुओं के बीच के समय को मापने की आवश्यकता हो सकती है, जो इसके साथ काम नहीं करेगाwithबयान। पाइथन की बहुत सारी चतुराई को आजमाने के बाद, यहाँ सरल उपाय है जो मुझे सबसे अच्छा लगता है:

from time import time
_tstart_stack = []

def tic():
    _tstart_stack.append(time())

def toc(fmt="Elapsed: %s s"):
    print fmt % (time() - _tstart_stack.pop())

चूंकि यह शुरुआती समय को एक स्टैक पर धकेलने से काम करता है, इसलिए यह tics और tocs के कई स्तरों के लिए सही ढंग से काम करेगा । यह tocअतिरिक्त जानकारी प्रदर्शित करने के लिए स्टेटमेंट के प्रारूप स्ट्रिंग को बदलने की अनुमति देता है , जो मुझे एली की Timerकक्षा के बारे में पसंद आया ।

किसी कारण से मैं शुद्ध पायथन कार्यान्वयन के ओवरहेड से चिंतित था, इसलिए मैंने एक सी एक्सटेंशन मॉड्यूल का भी परीक्षण किया:

#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);
}

यह MacOSX के लिए है, और मैंने यह जांचने के लिए कोड को छोड़ दिया lvlहै कि क्या यह संक्षिप्तता के लिए बाहर है। tictoc.res()अपने सिस्टम पर लगभग 50 नैनोसेकंड के एक रिज़ॉल्यूशन का उत्पादन करते समय , मैंने पाया कि किसी भी पायथन स्टेटमेंट को मापने का घबराना माइक्रोसेकंड रेंज में आसानी से होता है (और बहुत अधिक जब आईपिथॉन से उपयोग किया जाता है)। इस बिंदु पर, पायथन कार्यान्वयन का ओवरहेड नगण्य हो जाता है, ताकि इसे सी कार्यान्वयन के समान आत्मविश्वास के साथ उपयोग किया जा सके।

मैंने पाया कि tic-toc-approach की उपयोगिता व्यावहारिक रूप से कोड ब्लॉक तक सीमित है जो निष्पादित करने के लिए 10 से अधिक माइक्रोसेकंड लेते हैं। उसके नीचे, औसत रणनीति की तरह timeitएक वफादार माप प्राप्त करने के लिए आवश्यक हैं।


1
बहुत सुंदर, @Stefan - विश्वास नहीं कर सकता कि यह बहुत कम रेटेड है। धन्यवाद!
thclark

10

आप ticऔर tocसे उपयोग कर सकते हैं ttictoc। इसके साथ स्थापित करें

pip install ttictoc

और उन्हें अपनी स्क्रिप्ट में अनुसरण के रूप में आयात करें

from ttictoc import tic,toc
tic()
# Some code
print(toc())

8

मैंने सिर्फ नेस्टेड टिक टॉक्स प्राप्त करने के लिए एक मॉड्यूल [tictoc.py] बनाया है, जो कि मैटलैब करता है।

from time import time

tics = []

def tic():
    tics.append(time())

def toc():
    if len(tics)==0:
        return None
    else:
        return time()-tics.pop()

और यह इस तरह से काम करता है:

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

मुझे उम्मीद है यह मदद करेगा।


MATLAB से टिक / टो की अच्छी प्रतिकृति!
मैट

1
मुझे आपको चेतावनी देनी चाहिए कि जब 1 से अधिक मॉड्यूल द्वारा एक साथ उपयोग किया जाता है तो यह वांछित व्यवहार नहीं कर सकता है, क्योंकि (एएफएआईके) मॉड्यूल एकल के समान व्यवहार करते हैं।
एंटोनिमो

3

timeitमॉड्यूल पर एक नज़र है । यह वास्तव में समतुल्य नहीं है, लेकिन यदि आप जिस कोड को समय करना चाहते हैं वह एक फ़ंक्शन के अंदर है तो आप आसानी से इसका उपयोग कर सकते हैं।


हां, timeitबेंचमार्क के लिए सबसे अच्छा है। यह भी एक समारोह होने की जरूरत नहीं है, आप अचानक जटिल बयान पारित कर सकते हैं।

10
खैर, पासिंग कोड जो एक बहुत ही साधारण फ़ंक्शन कॉल नहीं है क्योंकि एक स्ट्रिंग बहुत बदसूरत है।
थोमास्टर

2
pip install easy-tictoc

कोड में:

from tictoc import tic, toc

tic()

#Some code

toc()

अस्वीकरण: मैं इस पुस्तकालय का लेखक हूं।


कृपया किसी अन्य उत्तर की प्रतिलिपि न करें, भले ही वह आपका अपना हो। stackoverflow.com/a/59271862/8239061
सीक्रेटएजेंटमैन

1

यह एक आवरण का उपयोग करके भी किया जा सकता है। समय रखने का बहुत सामान्य तरीका।

इस उदाहरण कोड में रैपर किसी भी फ़ंक्शन को लपेटता है और फ़ंक्शन को निष्पादित करने के लिए आवश्यक समय की मात्रा को प्रिंट करता है:

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

आवरण कार्य, टाइमथिस को डेकोरेटर कहा जाता है। थोड़ा और अधिक विस्तृत विवरण, यहाँ: medium.com/pythonhive/…
Mircea

1

मैंने समय बदलने के लिए ctor __init__()और dtor का उपयोग करने के लिए @Eli Bendersky के उत्तर को थोड़ा बदल दिया __del__(), ताकि मूल कोड को इंडेंट किए बिना इसे और अधिक आसानी से उपयोग किया जा सके:

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)

उपयोग करने के लिए, सरल कुछ स्थानीय दायरे की शुरुआत में टाइमर ("ब्लाब्लह") डालते हैं। व्यतीत समय गुंजाइश के अंत में मुद्रित किया जाएगा:

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

यह प्रिंट करता है:

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

3
इस कार्यान्वयन के साथ एक समस्या यह तथ्य है, कि timerअंतिम कॉल के बाद डिलीट नहीं किया जाता है, अगर forलूप के बाद कोई अन्य कोड आता है । अंतिम टाइमर मान प्राप्त करने के लिए, किसी को लूप के timerबाद हटाना या अधिलेखित करना चाहिए for, जैसे timer = None
bastelflp

1
@bastelflp बस एहसास हुआ कि मुझे आपका मतलब गलत लगा ... आपके सुझाव को अब कोड में शामिल कर लिया गया है। धन्यवाद।
शाओहुआ ली

1

एली के जवाब को पायथन 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)

एली की तरह, इसे एक संदर्भ प्रबंधक के रूप में इस्तेमाल किया जा सकता है:

import time 
with Timer('Count'):
    for i in range(0,10_000_000):
        pass

आउटपुट:

[Count] Elapsed: 0.27 seconds

मैंने रिपोर्ट किए गए समय (सेकंड) की इकाइयों को प्रिंट करने और कैन द्वारा सुझाए गए अंकों की संख्या को ट्रिम करने के लिए भी अपडेट किया है, और लॉग फ़ाइल में संलग्न करने के विकल्प के साथ भी। लॉगिंग सुविधा का उपयोग करने के लिए आपको डेटटाइम आयात करना होगा:

import time
import datetime 
with Timer('Count', 'log.txt'):    
    for i in range(0,10_000_000):
        pass

0

स्टीफन और एंटोनिमो के उत्तरों पर निर्माण, मैंने डाल दिया

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

एक utils.pyमॉड्यूल में, और मैं इसे एक के साथ उपयोग करता हूं

from utils import Tictoc
tic, toc = Tictoc()

इस तरफ

  • आप बस का उपयोग कर सकते हैं tic(), toc()और उन्हें मतलाब की तरह घोंसला बना सकते हैं
  • वैकल्पिक रूप से, आप उन्हें नाम कर सकते हैं: tic(1), toc(1)या tic('very-important-block'), toc('very-important-block')और अलग-अलग नामों के साथ टाइमर हस्तक्षेप नहीं करेगा
  • उन्हें इस तरह से आयात करना मॉड्यूल का उपयोग करने के बीच हस्तक्षेप को रोकता है।

(यहाँ toc बीता हुआ समय प्रिंट नहीं करता है, लेकिन इसे लौटाता है।)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.