পাইথন সময় পরিমাপ ফাংশন


121

প্রতিটি ফাংশনে ব্যয় করা সময় পরীক্ষা করতে এবং তার নামটি তার সময়ের সাথে মুদ্রণের জন্য আমি একটি অজগর ফাংশন তৈরি করতে চাই, আমি কীভাবে ফাংশনের নামটি মুদ্রণ করতে পারি এবং যদি এর অন্য কোনও উপায় থাকে তবে আমাকে বলুন

def measureTime(a):
    start = time.clock() 
    a()
    elapsed = time.clock()
    elapsed = elapsed - start
    print "Time spent in (function name) is: ", elapsed

পাইথন প্রোফাইলিং সরঞ্জামগুলি আপনাকে ফাংশনটির নাম এবং প্রতিটিটিতে সময় ব্যয় করতে পারে। এখানে পড়ুন: docs.python.org/library/profile.html
রোডমাস্টার

timeitপরিমাপের জন্য আরও ভাল ব্যবহার । এটি নিখুঁত নয়, তবে এটি এখন পর্যন্ত আপনার ছুরিকাঘাত করে এবং timeitনিজের চেয়ে ভাল কিছু বেতার চেয়ে এটি ব্যবহার করা আরও সহজ ।

উত্তর:


240

প্রথম এবং সর্বাগ্রে, আমি অত্যন্ত প্রোফাইলার ব্যবহার বা কমপক্ষে ব্যবহারের টাইমিট ব্যবহার করার পরামর্শ দিচ্ছি

তবে আপনি যদি নিজের টাইমিং পদ্ধতিটি কঠোরভাবে শিখতে চান তবে এখানে ডেকরেটার ব্যবহার শুরু করার জন্য কোথাও এখানে।

পাইথন 2:

def timing(f):
    def wrap(*args):
        time1 = time.time()
        ret = f(*args)
        time2 = time.time()
        print '%s function took %0.3f ms' % (f.func_name, (time2-time1)*1000.0)
        return ret
    return wrap

এবং ব্যবহারটি খুব সহজ, কেবল @ টেমিং ডেকরেটারটি ব্যবহার করুন:

@timing
def do_work():
  #code

পাইথন 3:

def timing(f):
    def wrap(*args, **kwargs):
        time1 = time.time()
        ret = f(*args, **kwargs)
        time2 = time.time()
        print('{:s} function took {:.3f} ms'.format(f.__name__, (time2-time1)*1000.0))

        return ret
    return wrap

নোট আমি f.func_nameফাংশনটির নামটি স্ট্রিং হিসাবে (পাইথন 2 তে), বা f.__name__ পাইথন 3 এ পেতে কল করছি ।


4
আমি যা চাই ঠিক তাই :) ... তবে আপনি লোকেরা আমাকে পাইথন প্রোফাইলার ব্যবহার করতে রাজি
করিয়েছিলেন

3
দেখে মনে হচ্ছে এটি সময় থেকে সময় (সময়) মাইক্রোসেকেন্ডে সময় রিপোর্ট? ডকুমেন্টেশনটি বলে যে এটি সেকেন্ডের মধ্যে ডকুমেন্টস.পাইথন.আর.গু
রাহুল ঝা

ফলকটিতে ফলন ব্যবহারের পরে এটি কার্যকর হতে পারে না। আমি কীভাবে এখনও এই পদ্ধতিটি ব্যবহার করতে পারি এবং ফলন ব্যবহার করতে পারি?
জিওমো

Def টাইমিং (এফ): ডিএফ র‌্যাপ (* আরগস, ** কোয়ার্গস): টাইম 1 = টাইম.টাইম () রেট = এফ (* আরগস, ** কোয়ার্গস) সময় 2 = সময়.টাইম () মুদ্রণের% s ফাংশনটি% 0.3 গ্রহণ করেছে f এমএস '% (f.func_name, (সময় 2-সময় 1) * 1000) রিটার্ন রিটার্ন মোড়ানো
বিবেক বগেরিয়া

1
নিজে লেখার অসুবিধা কি? অতিবাহিত সময়ের একটি তালিকা সংরক্ষণ এবং তাদের বিতরণ পরীক্ষা করা কি সহজ?
পিট

51

timeitমডিউলটির সাথে খেলার পরে , আমি এর ইন্টারফেসটি পছন্দ করি না, যা নিম্নলিখিত দুটি পদ্ধতির তুলনায় এত মার্জিত নয়।

নিম্নলিখিত কোডটি পাইথন 3 এ রয়েছে।

সাজসজ্জার পদ্ধতি

@ মাইক এর পদ্ধতিতে এটি প্রায় একই রকম। এটিকে আরও ভাল করতে এখানে আমি যুক্ত kwargsএবং functoolsমোড়ানো করি।

def timeit(func):
    @functools.wraps(func)
    def newfunc(*args, **kwargs):
        startTime = time.time()
        func(*args, **kwargs)
        elapsedTime = time.time() - startTime
        print('function [{}] finished in {} ms'.format(
            func.__name__, int(elapsedTime * 1000)))
    return newfunc

@timeit
def foobar():
    mike = Person()
    mike.think(30)

প্রসঙ্গ ব্যবস্থাপক পদ্ধতি

from contextlib import contextmanager

@contextmanager
def timeit_context(name):
    startTime = time.time()
    yield
    elapsedTime = time.time() - startTime
    print('[{}] finished in {} ms'.format(name, int(elapsedTime * 1000)))

উদাহরণস্বরূপ, আপনি এটি ব্যবহার করতে পারেন:

with timeit_context('My profiling code'):
    mike = Person()
    mike.think()

এবং withব্লকের কোডটির সময়সীমা নির্ধারণ করা হবে।

উপসংহার

প্রথম পদ্ধতিটি ব্যবহার করে, আপনি সাধারণ কোডটি পেতে ইয়েলি সাজসজ্জারকে মন্তব্য করতে পারেন। তবে এটি কেবল একটি ফাংশন সময় করতে পারে। যদি আপনার কোডের কিছু অংশ থাকে যা আপনি এটিকে কোনও ফাংশন হিসাবে তৈরি করবেন না, তবে আপনি দ্বিতীয় পদ্ধতিটি চয়ন করতে পারেন।

উদাহরণস্বরূপ, এখন আপনার আছে

images = get_images()
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)

এখন আপনি bigImage = ...লাইন সময় করতে চান । আপনি যদি এটি কোনও ফাংশনে পরিবর্তন করেন তবে তা হবে:

images = get_images()
bitImage = None
@timeit
def foobar():
    nonlocal bigImage
    bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)

দেখতে খুব দুর্দান্ত লাগছে না ... আপনি পাইথন 2 এ থাকলে কী nonlocalকীওয়ার্ড নেই।

পরিবর্তে, দ্বিতীয় পদ্ধতিটি এখানে খুব ভাল ফিট করে:

images = get_images()
with timeit_context('foobar'):
    bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)

আকর্ষণীয় অবদান, তবে আমি এটি অকেজো বলে মনে করি যে আপনি ডেকরেটার পদ্ধতিতে উল্লেখ করেছেন, আপনাকে timeitইন্টারফেস পরিবর্তন করতে হবে এবং মডিউলটির wraps()কার্যকারিতাটি ব্যবহার করতে হবে functools। আমি বোঝাতে চাইছি যে সমস্ত অতিরিক্ত কোডটি প্রয়োজনীয় নয়।
বিল্লাল বেগেরাদজ

1
প্রয়োজনimport functools
গিলাইম শেভালিয়ার

1
মনে রাখবেন যে আপনার সাজসজ্জাটি মূল ফাংশনের ফেরতের মানটি
মার্ক ভ্যান ডেইলে

11

timeitমডিউলে সমস্যা কী তা আমি দেখছি না । এটি সম্ভবত এটি করার সহজতম উপায়।

import timeit
timeit.timeit(a, number=1)

ফাংশনগুলিতে যুক্তি পাঠানোও সম্ভব। আপনার যা দরকার তা হ'ল সাজসজ্জা ব্যবহার করে আপনার ফাংশনটি মোড়ানো। এখানে আরও ব্যাখ্যা: http://www.pythoncentral.io/time-a-python-function/

আপনার নিজের সময় বিবরণী লেখার ক্ষেত্রে আপনি আগ্রহী হতে পারেন এমন একমাত্র ক্ষেত্রে হ'ল যদি আপনি একবারে কোনও ফাংশন পরিচালনা করতে চান এবং তার ফেরতের মানও পেতে চান।

timeitমডিউলটি ব্যবহারের সুবিধা হ'ল এটি আপনাকে মৃত্যুদন্ড কার্যকর করার সংখ্যা পুনরাবৃত্তি করতে দেয় । এটি প্রয়োজনীয় হতে পারে কারণ অন্যান্য প্রক্রিয়াগুলি আপনার সময়ের যথাযথতার সাথে হস্তক্ষেপ করতে পারে। সুতরাং, আপনার এটি একাধিকবার চালানো উচিত এবং সর্বনিম্ন মানটি দেখুন।


3
মোড়ক এবং সজ্জক ব্যবহার করে ফাংশনটিতে যুক্তি প্রেরণ করছেন? না কেন timeit.timeit(lambda: func(a,b,c), number=1)? টার্মিনালে অনুমানমূলক সমাধানে পরীক্ষা করার সময় আমি এটি ব্যবহার করি।
জ্যাক

10

টাইমাইটের দুটি বড় ত্রুটি রয়েছে: এটি ফাংশনের রিটার্ন মানটি ফিরিয়ে দেয় না এবং এটি ইভাল ব্যবহার করে, যার জন্য আমদানির জন্য অতিরিক্ত সেটআপ কোড পাস করা প্রয়োজন। এটি সহজ এবং মার্জিতভাবে উভয় সমস্যার সমাধান করে:

def timed(f):
  start = time.time()
  ret = f()
  elapsed = time.time() - start
  return ret, elapsed

timed(lambda: database.foo.execute('select count(*) from source.apachelog'))
(<sqlalchemy.engine.result.ResultProxy object at 0x7fd6c20fc690>, 4.07547402381897)

ধন্যবাদ! টাইমিট অ্যাপাচি স্পার্কের সাথে ভাল কাজ করে না কারণ আপনাকে সমস্ত স্পার্ক নির্ভরতা আমদানি করতে হবে, এবং কে এটি করতে পারে যে একটি বড় পুরানো স্ট্রিং তৈরি করতে চায়? এই সমাধানটি অনেক সহজ এবং আরও নমনীয়।
পল

4

সময় দেওয়ার জন্য একটি সহজ সরঞ্জাম রয়েছে is https://github.com/RalphMao/PyTimer

এটি সাজসজ্জার মতো কাজ করতে পারে :

from pytimer import Timer
@Timer(average=False)      
def matmul(a,b, times=100):
    for i in range(times):
        np.dot(a,b)        

আউটপুট:

matmul:0.368434
matmul:2.839355

এটি নেমস্পেস কন্ট্রোল সহ প্লাগ-ইন টাইমারের মতোও কাজ করতে পারে (আপনি যদি এমন কোনও ফাংশনে সন্নিবেশ করিয়ে থাকেন তবে অনেক কোড রয়েছে এবং অন্য কোথাও বলা যেতে পারে) সহায়ক।

timer = Timer()                                           
def any_function():                                       
    timer.start()                                         

    for i in range(10):                                   

        timer.reset()                                     
        np.dot(np.ones((100,1000)), np.zeros((1000,500)))
        timer.checkpoint('block1')                        

        np.dot(np.ones((100,1000)), np.zeros((1000,500)))
        np.dot(np.ones((100,1000)), np.zeros((1000,500)))
        timer.checkpoint('block2')                        
        np.dot(np.ones((100,1000)), np.zeros((1000,1000)))

    for j in range(20):                                   
        np.dot(np.ones((100,1000)), np.zeros((1000,500)))
    timer.summary()                                       

for i in range(2):                                        
    any_function()                                        

আউটপুট:

========Timing Summary of Default Timer========
block2:0.065062
block1:0.032529
========Timing Summary of Default Timer========
block2:0.065838
block1:0.032891

আশা করি এটি সাহায্য করবে


3

সাজসজ্জার পাইথন লাইব্রেরি ব্যবহার করে সাজসজ্জার পদ্ধতি:

import decorator

@decorator
def timing(func, *args, **kwargs):
    '''Function timing wrapper
        Example of using:
        ``@timing()``
    '''

    fn = '%s.%s' % (func.__module__, func.__name__)

    timer = Timer()
    with timer:
        ret = func(*args, **kwargs)

    log.info(u'%s - %0.3f sec' % (fn, timer.duration_in_seconds()))
    return ret

আমার ব্লগে পোস্ট দেখুন:

mobilepro.pl ব্লগে পোস্ট করুন

গুগল প্লাসে আমার পোস্ট


1

এটি করার আমার পদ্ধতি:

from time import time

def printTime(start):
    end = time()
    duration = end - start
    if duration < 60:
        return "used: " + str(round(duration, 2)) + "s."
    else:
        mins = int(duration / 60)
        secs = round(duration % 60, 2)
        if mins < 60:
            return "used: " + str(mins) + "m " + str(secs) + "s."
        else:
            hours = int(duration / 3600)
            mins = mins % 60
            return "used: " + str(hours) + "h " + str(mins) + "m " + str(secs) + "s."

start = time()ফাংশন / লুপগুলি কার্যকর করতে আগের মতো একটি ভেরিয়েবল সেট করুন এবং printTime(start)ব্লকের ঠিক পরে।

এবং আপনি উত্তর পেয়েছি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.