समय मॉड्यूल के साथ बीता हुआ समय मापने


337

अजगर में समय मॉड्यूल के साथ बीता समय को मापना संभव है? अगर ऐसा है, तो मैं वह कैसे करू?

मुझे यह करने की आवश्यकता है कि यदि कर्सर एक निश्चित अवधि के लिए एक विजेट में होता है, तो एक घटना होती है।


3
NB कि किसी भी उत्तर का उपयोग time.time()गलत है। सबसे सरल उदाहरण है अगर माप अवधि के दौरान सिस्टम का समय बदल जाता है।
ऑरेंजडॉग

किसी ईवेंट को फायर करने के संबंध में आपके मूल प्रश्न के लिए यदि कोई विज़िटर विजेट पर एक निश्चित अवधि के लिए रहता है, तो docs.python.org/3/library/threading.html आपको वह सब प्रदान करता है, जो मुझे लगता है। मल्टीथ्रेडिंग और टाइमआउट के साथ एक शर्त चर समाधान में से एक हो सकता है। हालाँकि, आपकी परिस्थितियाँ वर्तमान में उत्तर देने के लिए अस्पष्ट हैं।
तोरा

2
कोई कारण नहीं है कि किसी को time.time()आधुनिक अजगर में बीता समय मापने के लिए उपयोग किया जाना चाहिए (मैनुअल परिवर्तन, बहाव, छलांग सेकंड आदि से प्रभावित)। नीचे दिए गए इस उत्तर को अधिक होने की आवश्यकता है, इस प्रश्न पर विचार करते हुए अब Google में बीते समय को मापने के लिए शीर्ष परिणाम है।
एनपीआरएस

आप cProfile profiler के साथ समय भी माप सकते हैं: docs.python.org/3/library/profile.html#module-cProfile stackoverflow.com/questions/582336/…
एंटोन

1
@NPras "आधुनिक अजगर" को भूल जाते हैं। इसका उपयोग करना हमेशा गलत था time.time()
ऑरेंजडॉग

जवाबों:


514
start_time = time.time()
# your code
elapsed_time = time.time() - start_time

आप विभिन्न कार्यों के निष्पादन समय के मापन को सरल बनाने के लिए साधारण डेकोरेटर भी लिख सकते हैं:

import time
from functools import wraps

PROF_DATA = {}

def profile(fn):
    @wraps(fn)
    def with_profiling(*args, **kwargs):
        start_time = time.time()

        ret = fn(*args, **kwargs)

        elapsed_time = time.time() - start_time

        if fn.__name__ not in PROF_DATA:
            PROF_DATA[fn.__name__] = [0, []]
        PROF_DATA[fn.__name__][0] += 1
        PROF_DATA[fn.__name__][1].append(elapsed_time)

        return ret

    return with_profiling

def print_prof_data():
    for fname, data in PROF_DATA.items():
        max_time = max(data[1])
        avg_time = sum(data[1]) / len(data[1])
        print "Function %s called %d times. " % (fname, data[0]),
        print 'Execution time max: %.3f, average: %.3f' % (max_time, avg_time)

def clear_prof_data():
    global PROF_DATA
    PROF_DATA = {}

उपयोग:

@profile
def your_function(...):
    ...

आप एक साथ एक से अधिक फ़ंक्शन कर सकते हैं। फिर माप प्रिंट करने के लिए बस print_prof_data () को कॉल करें:


11
आप प्रोफ़ाइलहुक pip install profilehooks और इसके मुखपृष्ठ
पेज

11
ध्यान दें कि अजगर 3.3 के बाद से, एक शायद का उपयोग करना चाहिए time.monotonic()बल्कि उसके बाद time.time()जब समय समाप्ति या अवधि को मापने। docs.python.org/3/library/time.html#time.monotonic
डेबिल्स्की

39
यहाँ जोड़ने / ध्यान देने योग्य है कि बीते हुए समय के लिए माप की इकाई सेकंड होगी।
एरिक क्रैमर

4
@EricKramer धन्यवाद! माप की इकाई को परिभाषित किए बिना माप की व्याख्या करते हुए मेरा विशाल पालतू पेशाब। और पहली बार पायथन में पायस को डुबोने वाले एक .NET पुरुष के रूप में, मैंने स्वचालित रूप से "मिलीसेकंड" सोचा।
बजे एडम प्लोचर

2
काम नहीं करता है (उदाहरण के लिए) सिस्टम क्लॉक को बदल दिया जाता है, और सबसेकंड रिज़ॉल्यूशन नहीं हो सकता है। सही उत्तर: stackoverflow.com/a/47637891/476716
ऑरेंजडॉग

97

time.time() नौकरी करेंगे।

import time

start = time.time()
# run your code
end = time.time()

elapsed = end - start

आप इस प्रश्न को देखना चाह सकते हैं , लेकिन मुझे नहीं लगता कि यह आवश्यक होगा।


6
हाँ, समय सेकंड में है
एरिक क्रैमर

आपको start_time में परिवर्तन करना चाहिए।
ज़ोरान पांडोव्स्की

time.time()एक बुरा विचार है क्योंकि सिस्टम क्लॉक को रीसेट किया जा सकता है जो आपको समय में वापस चला जाएगा। time.monotonic()इस पर ध्यान देता है (एकरस = यह केवल आगे बढ़ता है)। time.perf_counter()भी मोनोटोनिक है, लेकिन यहां तक ​​कि उच्च सटीकता भी है, इसलिए यह दीवार-घड़ी के समय के लिए अनुशंसित है।
xjcl

76

उन उपयोगकर्ताओं के लिए जो बेहतर स्वरूपण चाहते हैं,

import time
start_time = time.time()
# your script
elapsed_time = time.time() - start_time
time.strftime("%H:%M:%S", time.gmtime(elapsed_time))

2 सेकंड के लिए प्रिंट आउट होगा:

'00:00:02'

और 7 मिनट एक सेकंड के लिए:

'00:07:01'

ध्यान दें कि gmtime के साथ न्यूनतम समय इकाई सेकंड है। यदि आपको माइक्रोसेकंड की आवश्यकता है, तो निम्नलिखित पर विचार करें:

import datetime
start = datetime.datetime.now()
# some code
end = datetime.datetime.now()
elapsed = end - start
print(elapsed)
# or
print(elapsed.seconds,":",elapsed.microseconds) 

strftime प्रलेखन


1
आपके उत्तर के लिए धन्यवाद, जो मुझे प्रेरित करता है। मैं e = time.time() - start_time ; print("%02d:%02d:%02d" % (e // 3600, (e % 3600 // 60), (e % 60 // 1)))उस पैदावार का उपयोग करने जा रहा हूं जो लगभग 24 घंटे से अधिक समय तक रहने वाली स्थिति को कवर करता है।
तोरा

@Tora आप भविष्य की संगतता समस्याओं के लिए% 02d के बजाय "{}" प्रारूप () को देखना चाहते हैं।
रटगेर हॉफस्टैड

2
धन्यवाद! अब मुझे नए की आदत हो रही है। '{: 02 डी}: {: 02 डी}: {: 02 डी}'। प्रारूप (ई // 3600, (ई% 3600 // 60), ई% 60)
तोरा

क्या आप time.monotonic()अन्य उत्तरों की तरह उपयोग कर सकते हैं ?
एंडोलिथ

elapsed.secondsअवधि एक दिन से अधिक होगी तो गलत होगा। आप elapsed.total_seconds()लचीला होना चाहते हैं
ऐश बर्लिन-टेलर

51

बीते हुए समय (पायथन 3.3 के बाद से) के सर्वोत्तम उपाय के लिए उपयोग करें time.perf_counter()

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

घंटों / दिनों के क्रम पर माप के लिए, आप उप-द्वितीय रिज़ॉल्यूशन के बारे में परवाह नहीं करते हैं, इसलिए time.monotonic()इसके बजाय उपयोग करें ।

एक मोनोटोनिक घड़ी का मान (भिन्नात्मक सेकंड में) लौटें, यानी एक ऐसी घड़ी जो पीछे की तरफ नहीं जा सकती। सिस्टम घड़ी अपडेट से घड़ी प्रभावित नहीं होती है। लौटाए गए मान का संदर्भ बिंदु अपरिभाषित है, ताकि केवल लगातार कॉल के परिणामों के बीच का अंतर मान्य हो।

कई कार्यान्वयन में, ये वास्तव में एक ही बात हो सकती है।

3.3 से पहले, आप के साथ फंस गए हैं time.clock()

यूनिक्स पर, सेकंड में व्यक्त फ्लोटिंग पॉइंट संख्या के रूप में वर्तमान प्रोसेसर समय वापस करें। सटीक, और वास्तव में "प्रोसेसर समय" के अर्थ की बहुत परिभाषा, उसी नाम के सी फ़ंक्शन पर निर्भर करता है।

Windows पर, यह फ़ंक्शन Win32 फ़ंक्शन QueryPerformanceCounter () के आधार पर, फ़्लोटिंग पॉइंट नंबर के रूप में इस फ़ंक्शन पर पहली कॉल के बाद से दीवार-घड़ी सेकंड वापस आ जाता है। रिज़ॉल्यूशन आमतौर पर एक माइक्रोसेकंड से बेहतर है।


पायथन 3.7 के लिए अद्यतन

Python 3.7 में नया PEP 564 है - नैनोसेकंड रिज़ॉल्यूशन के साथ नए समय फ़ंक्शन जोड़ें।

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

perf_counter()लगभग 100 दिनों के बाद संकल्प टूटने लगता है । इसलिए उदाहरण के लिए एक वर्ष के बाद, सबसे छोटा अंतराल (0 से अधिक) यह माप सकता है कि यह कब शुरू हुआ था।


पायथन 3.8 के लिए अद्यतन

time.clock अब चला गया है।


"कई कार्यान्वयन में, ये वास्तव में एक ही बात हो सकती है।" सच है, मेरे लिनक्स टकसाल पीसी पर, time.monotonic () और time.perf_counter () समान मान वापस करने के लिए लगता है।
xjcl

7

लंबी अवधि के लिए।

import time
start_time = time.time()
...
e = int(time.time() - start_time)
print('{:02d}:{:02d}:{:02d}'.format(e // 3600, (e % 3600 // 60), e % 60))

छपता था

00:03:15

यदि 24 घंटे से अधिक हो

25:33:57

जो रटगेर हॉस्टस्ट के उत्तर से प्रेरित है। शुक्रिया रटगर!


6

आपको वर्तमान समय जानने के लिए समय आयात करने और फिर time.time () पद्धति का उपयोग करने की आवश्यकता है।

import time

start_time=time.time() #taking current time as starting time

#here your code

elapsed_time=time.time()-start_time #again taking current time - starting time 

3

समय की चीजों का एक और अच्छा तरीका अजगर संरचना के साथ उपयोग करना है ।

संरचना के साथ स्वचालित रूप से __enter__ और __exit__ तरीकों को कॉल किया जाता है, जो वास्तव में हमें चीजों को समय की आवश्यकता है।

चलो एक बनाएँ टाइमर वर्ग।

from time import time

class Timer():
    def __init__(self, message):
        self.message = message
    def __enter__(self):
        self.start = time()
        return None  # could return anything, to be used like this: with Timer("Message") as value:
    def __exit__(self, type, value, traceback):
        elapsed_time = (time() - self.start) * 1000
        print(self.message.format(elapsed_time))

फिर, कोई इस तरह टाइमर का उपयोग कर सकता है:

with Timer("Elapsed time to compute some prime numbers: {}ms"):
    primes = []
    for x in range(2, 500):
        if not any(x % p == 0 for p in primes):
            primes.append(x)
    print("Primes: {}".format(primes))

परिणाम निम्नलिखित है:

प्राइम्स: [२, ३, ५,:, ११, १३, १ ९, १ ९, २३, २३, २ ९, ३१, ३,, ४१, ४१, ४ 41, ५,, ५ 61, ६,, ,१,,,,, ९, ,३,, ९,, ९। , 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227 , 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 337, 337, 337, 347, 349, 359, 359, 367, 373, 373 , 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499]

कुछ प्रमुख संख्याओं की गणना करने का समय: 5.01704216003418ms


2

वादिम शेंडर प्रतिक्रिया बहुत अच्छी है। आप नीचे दिए गए सरल डेकोरेटर का भी उपयोग कर सकते हैं:

import datetime
def calc_timing(original_function):                            
    def new_function(*args,**kwargs):                        
        start = datetime.datetime.now()                     
        x = original_function(*args,**kwargs)                
        elapsed = datetime.datetime.now()                      
        print("Elapsed Time = {0}".format(elapsed-start))     
        return x                                             
    return new_function()  

@calc_timing
def a_func(*variables):
    print("do something big!")

1

प्रोग्रामिंग में, अलग-अलग परिणामों के साथ, समय को मापने के 2 मुख्य तरीके हैं :

>>> print(time.process_time()); time.sleep(10); print(time.process_time())
0.11751394000000001
0.11764988400000001  # took  0 seconds and a bit
>>> print(time.perf_counter()); time.sleep(10); print(time.perf_counter())
3972.465770326
3982.468109075       # took 10 seconds and a bit
  • प्रोसेसर का समय : यह वह समय है जब यह विशिष्ट प्रक्रिया सीपीयू पर सक्रिय रूप से निष्पादित की जाती है। नींद, एक वेब अनुरोध का इंतजार, या समय जब केवल अन्य प्रक्रियाओं को निष्पादित किया जाता है, इसमें योगदान नहीं होगा।

    • उपयोग time.process_time()
  • वॉल-क्लॉक टाइम : यह संदर्भित करता है कि "दीवार पर लटकी घड़ी पर" कितना समय बीत चुका है, अर्थात वास्तविक समय के बाहर।

    • उपयोग time.perf_counter()

      • time.time() दीवार-घड़ी के समय को भी मापता है, लेकिन रीसेट किया जा सकता है, इसलिए आप समय में वापस जा सकते हैं
      • time.monotonic() रीसेट नहीं किया जा सकता (मोनोटोनिक = केवल आगे जाता है) लेकिन की तुलना में कम परिशुद्धता है time.perf_counter()

0

यहां टेबिल आउटपुट के साथ वादिम शेंडर के चतुर कोड का अपडेट दिया गया है:

import collections
import time
from functools import wraps

PROF_DATA = collections.defaultdict(list)

def profile(fn):
    @wraps(fn)
    def with_profiling(*args, **kwargs):
        start_time = time.time()
        ret = fn(*args, **kwargs)
        elapsed_time = time.time() - start_time
        PROF_DATA[fn.__name__].append(elapsed_time)
        return ret
    return with_profiling

Metrics = collections.namedtuple("Metrics", "sum_time num_calls min_time max_time avg_time fname")

def print_profile_data():
    results = []
    for fname, elapsed_times in PROF_DATA.items():
        num_calls = len(elapsed_times)
        min_time = min(elapsed_times)
        max_time = max(elapsed_times)
        sum_time = sum(elapsed_times)
        avg_time = sum_time / num_calls
        metrics = Metrics(sum_time, num_calls, min_time, max_time, avg_time, fname)
        results.append(metrics)
    total_time = sum([m.sum_time for m in results])
    print("\t".join(["Percent", "Sum", "Calls", "Min", "Max", "Mean", "Function"]))
    for m in sorted(results, reverse=True):
        print("%.1f\t%.3f\t%d\t%.3f\t%.3f\t%.3f\t%s" % (100 * m.sum_time / total_time, m.sum_time, m.num_calls, m.min_time, m.max_time, m.avg_time, m.fname))
    print("%.3f Total Time" % total_time)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.