টাইমিট মডিউলটি কীভাবে ব্যবহার করবেন


351

আমি কী timeitকরে সে সম্পর্কে ধারণাটি বুঝতে পেরেছি তবে কীভাবে এটি আমার কোডটিতে প্রয়োগ করা যায় তা সম্পর্কে আমি নিশ্চিত নই।

আমি কীভাবে দুটি ফাংশন , এর সাথে insertion_sortএবং এর tim_sortসাথে তুলনা করতে পারি timeit?

উত্তর:


266

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

বাছাইয়ের জন্য কীভাবে একটি পরীক্ষা সেট আপ করা যায় তার একটি উদাহরণ এখানে রয়েছে:

>>> import timeit

>>> setup = '''
import random

random.seed('slartibartfast')
s = [random.random() for i in range(1000)]
timsort = list.sort
'''

>>> print min(timeit.Timer('a=s[:]; timsort(a)', setup=setup).repeat(7, 1000))
0.334147930145

নোট করুন যে বিবৃতিগুলির সিরিজটি প্রতিটি পাসে অরসেটেড ডেটার একটি নতুন কপি তৈরি করে।

এছাড়াও, পরিমাপ স্যুটটি সাতবার চালানোর এবং কেবল সেরা সময় রাখার সময় কৌশলটি নোট করুন - এটি আপনার সিস্টেমে চলমান অন্যান্য প্রক্রিয়ার কারণে পরিমাপের বিকৃতি হ্রাস করতে সত্যই সহায়তা করতে পারে।

টাইমিট সঠিকভাবে ব্যবহারের জন্য সেগুলি আমার টিপস। আশাকরি এটা সাহায্য করবে :-)


8
হ্যাঁ, এটিতে লিস্টের অনুলিপি রয়েছে (যা বাছাইয়ের তুলনায় খুব দ্রুত)। আপনি যদি অনুলিপি না করেন তবে প্রথম পাসের তালিকাটি বাছাই করে এবং বাকি পাসের কোনও কাজ করতে হবে না। আপনি যদি কেবল সাজানোর জন্য সময়টি জানতে চান, তবে উপরেরটিটি সাথে এবং ছাড়াই চালান এবং timsort(a)পার্থক্যটি গ্রহণ করুন :-)
রেমন্ড হেটিঙ্গার

আমি প্রতিটি সেটআপের জন্য 7 বার পুনরাবৃত্তি করার পরামর্শ দেব এবং তারপরে গড়; বরং অন্য রাউন্ডের চেয়ে বেশি। এইভাবে, যদি অন্য প্রক্রিয়াগুলির কারণে প্রতিটি স্পাইকে গড় হার না করে সম্পূর্ণ উপেক্ষা করার ভাল সম্ভাবনা থাকে।
সর্বোচ্চ

75
@ ম্যাক্স সময়কালের গড়ের চেয়ে কমপক্ষে () ব্যবহার করুন। এটি আমার কাছ থেকে, টিম পিটার্স এবং গাইডো ভ্যান রসুমের একটি প্রস্তাবনা। ক্যাচগুলি লোড করা হয় এবং সিস্টেম অন্যান্য কার্যক্রমে ব্যস্ত না হলে দ্রুততম সময়টি সেরা অ্যালগরিদমটি সম্পাদন করতে পারে। সমস্ত সময় গোলমাল - দ্রুততম সময় হ'ল কম শব্দ। এটি দেখানো সহজ যে দ্রুততম সময়গুলি সবচেয়ে পুনরুত্পাদনযোগ্য এবং তাই দুটি পৃথক বাস্তবায়নের সময় নির্ধারণের সময় সবচেয়ে কার্যকর।
রেমন্ড হেটেঙ্গার

4
আপনি 1000 ইনপুটগুলির জন্য গড় (ভাল, মোট, তবে এটি সমতুল্য) গণনা করুন ; তারপরে 7 বার পুনরাবৃত্তি করুন এবং সর্বনিম্ন নিন । আপনার গড় 1000 এরও বেশি ইনপুট দরকার কারণ আপনি গড় (সেরা-ক্ষেত্রে নয়) অ্যালগরিদম জটিলতা চান। আপনি যে কারণে দিয়েছেন তার জন্য আপনাকে ন্যূনতম প্রয়োজন। আমি ভেবেছিলাম যে আমি একটি ইনপুট বেছে নিয়ে, অ্যালগরিদমটি 7 বার চালিয়ে, সর্বনিম্ন গ্রহণ করে আপনার পদ্ধতির উন্নতি করতে পারি; তারপরে এটি 1000 টি বিভিন্ন ইনপুটগুলির জন্য পুনরাবৃত্তি করা এবং গড় নেওয়া। আমি যা বুঝতে পারি নি তা হ'ল আপনার .repeat(7,1000)ইতিমধ্যে এটি (একই বীজ ব্যবহার করে)! সুতরাং আপনার সমাধান নিখুঁত আইএমও।
সর্বাধিক

5
আমি কেবল এটি যোগ করতে পারি যে আপনি কীভাবে আপনার 7000 মৃত্যুদণ্ড কার্যকর করার বাজেট বরাদ্দ করেন (যেমন, .repeat(7, 1000)বনাম .repeat(2, 3500)বনাম .repeat(35, 200) সিস্টেম লোডের কারণে ত্রুটি কীভাবে ইনপুট ভেরিয়েবলের কারণে ত্রুটির সাথে তুলনা করে তা নির্ভর করে। চূড়ান্ত ক্ষেত্রে যদি আপনার সিস্টেমটি সর্বদা ভারী বোঝার মধ্যে থাকে এবং আপনি এক্সিকিউশন সময় বিতরণের বাম দিকে একটি দীর্ঘ পাতলা লেজ দেখতে পান (যখন আপনি এটি একটি বিরল অলস অবস্থায় দেখেন) তবে আপনি এটির .repeat(7000,1)চেয়েও বেশি কার্যকর হতে .repeat(7,1000)পারেন 7000 রানের বেশি বাজেট করতে পারে না।
সর্বাধিক

277

যদি আপনি timeitএকটি ইন্টারেক্টিভ পাইথন সেশনে ব্যবহার করতে চান তবে দুটি সুবিধাজনক বিকল্প রয়েছে:

  1. আইপিথন শেলটি ব্যবহার করুন । এটি সুবিধাজনক %timeitবিশেষ ফাংশন বৈশিষ্ট্যযুক্ত :

    In [1]: def f(x):
       ...:     return x*x
       ...: 
    
    In [2]: %timeit for x in range(100): f(x)
    100000 loops, best of 3: 20.3 us per loop
  2. পাইথন স্ট্যান্ডার্ড ইন্টারপ্রেটারে আপনি ইন্টারেক্টিভ সেশনের সময় __main__সেটআপ স্টেটমেন্ট থেকে আমদানি করে ফাংশন এবং অন্যান্য নামগুলি অ্যাক্সেস করতে পারেন :

    >>> def f(x):
    ...     return x * x 
    ... 
    >>> import timeit
    >>> timeit.repeat("for x in range(100): f(x)", "from __main__ import f",
                      number=100000)
    [2.0640320777893066, 2.0876040458679199, 2.0520210266113281]

97
from __main__ import fকৌশলটি দেখানোর জন্য +1 । আমি মনে করি না যে এটি হওয়া উচিত হিসাবে এটি ব্যাপকভাবে পরিচিত। এটি এই জাতীয় ক্ষেত্রে কার্যকর যেখানে কোনও ফাংশন বা পদ্ধতি কল সময়কাল হচ্ছে। অন্যান্য ক্ষেত্রে (ধাপের একটি সিরিজের সময় নির্ধারণ), এটি কম সহায়ক কারণ এটি ফাংশন কল ওভারহেডের সাথে পরিচিত করে।
রেমন্ড হেটেঞ্জার

15
আপনি কেবল করতে পারেন%timeit f(x)
কেয়েড

দ্রষ্টব্য: "ইম্পোর্ট এফ" সেটআপটি এফ এ দ্রুত স্থানীয় পঠনের অ্যাক্সেসকে পরিণত করে - যা সাধারণত সাধারণ কোডে একটি গ্লোবাল ফাংশন কল (সংক্ষিপ্ত দ্রুত ফাংশনের) প্রতিফলিত করে না। পাই 3.৫-তে রিয়েল গ্লোবাল সরবরাহ করা যেতে পারে: "সংস্করণ ৩.৩ এ পরিবর্তিত হয়েছে: alচ্ছিক গ্লোবালগুলির পরামিতি যুক্ত করা হয়েছিল" ;; সময়কালীন মডিউলটির গ্লোবালগুলির আগে যেখানে অনিবার্য (যা বেশি বোঝায় না)। সম্ভবত কলিং কোড ( sys._getframe(N).f_globals) এর গ্লোবালগুলি শুরু থেকেই ডিফল্ট হওয়া উচিত ছিল।
kxr

140

আমি আপনাকে একটি গোপনে রাখব: ব্যবহারের সর্বোত্তম উপায় timeitহ'ল কমান্ড লাইনে।

কমান্ড লাইনে, timeitসঠিক পরিসংখ্যান বিশ্লেষণ করে: এটি আপনাকে জানায় যে সংক্ষিপ্ততম রানটি কতটা সময় নিয়েছিল। এটি ভাল কারণ সময় নির্ধারণের সমস্ত ত্রুটি ইতিবাচক। সুতরাং সবচেয়ে স্বল্পতম সময়ের মধ্যে এতে ত্রুটি রয়েছে। নেতিবাচক ত্রুটি পাওয়ার কোনও উপায় নেই কারণ কোনও কম্পিউটার তার তুলনায় দ্রুত গতিতে পারে না!

সুতরাং, কমান্ড-লাইন ইন্টারফেস:

%~> python -m timeit "1 + 2"
10000000 loops, best of 3: 0.0468 usec per loop

এটা বেশ সহজ, তাই না?

আপনি জিনিস সেট আপ করতে পারেন:

%~> python -m timeit -s "x = range(10000)" "sum(x)"
1000 loops, best of 3: 543 usec per loop

যা দরকারী, খুব!

আপনি যদি একাধিক লাইন চান, আপনি শেলের স্বয়ংক্রিয় ধারাবাহিকতা ব্যবহার করতে পারেন বা পৃথক যুক্তি ব্যবহার করতে পারেন:

%~> python -m timeit -s "x = range(10000)" -s "y = range(100)" "sum(x)" "min(y)"
1000 loops, best of 3: 554 usec per loop

এটি একটি সেটআপ দেয়

x = range(1000)
y = range(100)

এবং সময়

sum(x)
min(y)

আপনি যদি দীর্ঘ স্ক্রিপ্ট পেতে চান তবে আপনাকে timeitপাইথন স্ক্রিপ্টের ভিতরে যেতে প্ররোচিত হতে পারে । আমি এড়িয়ে চলার পরামর্শ দিচ্ছি কারণ বিশ্লেষণ এবং সময় কমান্ড লাইনে আরও ভাল। পরিবর্তে, আমি শেল স্ক্রিপ্ট তৈরি করতে ঝোঁক:

 SETUP="

 ... # lots of stuff

 "

 echo Minmod arr1
 python -m timeit -s "$SETUP" "Minmod(arr1)"

 echo pure_minmod arr1
 python -m timeit -s "$SETUP" "pure_minmod(arr1)"

 echo better_minmod arr1
 python -m timeit -s "$SETUP" "better_minmod(arr1)"

 ... etc

একাধিক সূচনাগুলির কারণে এটি কিছুটা বেশি সময় নিতে পারে, তবে সাধারণত এটি কোনও বড় বিষয় নয়।


তবে আপনি যদি নিজের মডিউলটির ভিতরে ব্যবহার করতে চানtimeit ?

আচ্ছা, সহজ উপায়টি হ'ল:

def function(...):
    ...

timeit.Timer(function).timeit(number=NUMBER)

এবং এটি আপনাকে সংখ্যার বার চালানোর জন্য সংক্ষিপ্ত ( সর্বনিম্ন নয় !) সময় দেয়।

একটি ভাল বিশ্লেষণ পেতে, .repeatসর্বনিম্ন ব্যবহার করুন এবং নিন:

min(timeit.Timer(function).repeat(repeat=REPEATS, number=NUMBER))

আপনি সাধারণত ওভারহেড নিম্নের functools.partialপরিবর্তে এটির সাথে একত্রিত lambda: ...হন। সুতরাং আপনি যেমন কিছু থাকতে পারে:

from functools import partial

def to_time(items):
    ...

test_items = [1, 2, 3] * 100
times = timeit.Timer(partial(to_time, test_items)).repeat(3, 1000)

# Divide by the number of repeats
time_taken = min(times) / 1000

আপনি এটি করতে পারেন:

timeit.timeit("...", setup="from __main__ import ...", number=NUMBER)

যা আপনাকে কমান্ড-লাইন থেকে ইন্টারফেসের কাছাকাছি কিছু দিতে পারে তবে খুব কম শীতল পদ্ধতিতে। "from __main__ import ..."আপনার দ্বারা নির্মিত কৃত্রিম পরিবেশ ভিতরে আপনার প্রধান মডিউল থেকে কোড ব্যবহার করতে দেয় timeit

এটি লক্ষণীয় যে এটির জন্য একটি সুবিধাযুক্ত মোড়ক Timer(...).timeit(...)এবং তাই সময়োপযোগী বিশেষত ভাল নয়। আমি ব্যক্তিগতভাবে অনেক Timer(...).repeat(...)উপরে পছন্দ হিসাবে আমি উপরে দেখানো পছন্দ ।


সতর্কবাণী

timeitযে হোল্ডটি রয়েছে সেখানে সর্বত্র কয়েকটি গুপ্তচর রয়েছে ।

  • ওভারহেডের জন্য অ্যাকাউন্ট করা হয় না। বলুন যে আপনি সময় চান x += 1, সংযোজন কত সময় নেয় তা জানতে:

    >>> python -m timeit -s "x = 0" "x += 1"
    10000000 loops, best of 3: 0.0476 usec per loop

    ওয়েল, এটা না 0,0476 μs। আপনি কেবল জানেন যে এটি এর চেয়ে কম । সমস্ত ত্রুটি ইতিবাচক।

    সুতরাং চেষ্টা করুন এবং খাঁটি ওভারহেড সন্ধান করুন:

    >>> python -m timeit -s "x = 0" ""      
    100000000 loops, best of 3: 0.014 usec per loop

    ঠিক সময় থেকে এটি বেশ ভাল 30% ওভারহেড! এটি প্রচুর পরিমাণে আপেক্ষিক সময়গুলি কাটাতে পারে। তবে আপনি কেবল যুক্ত করার সময়গুলি সম্পর্কে সত্যই যত্নশীল ছিলেন ; xওভারহেড অন্তর্ভুক্ত করা প্রয়োজন চেহারা জন্য সময় :

    >>> python -m timeit -s "x = 0" "x"
    100000000 loops, best of 3: 0.0166 usec per loop

    পার্থক্যটি খুব বেশি বড় নয়, তবে এটি রয়েছে।

  • মিউটেশন পদ্ধতিগুলি বিপজ্জনক।

    >>> python -m timeit -s "x = [0]*100000" "while x: x.pop()"
    10000000 loops, best of 3: 0.0436 usec per loop

    তবে তা সম্পূর্ণ ভুল! xপ্রথম পুনরাবৃত্তির পরে খালি তালিকা। আপনাকে পুনর্নির্মাণ করতে হবে:

    >>> python -m timeit "x = [0]*100000" "while x: x.pop()"
    100 loops, best of 3: 9.79 msec per loop

    তবে তারপরে আপনার প্রচুর ওভারহেড রয়েছে। এর জন্য আলাদাভাবে অ্যাকাউন্ট করুন।

    >>> python -m timeit "x = [0]*100000"                   
    1000 loops, best of 3: 261 usec per loop

    নোট করুন যে ওভারহেডটি বিয়োগ করা এখানে যুক্তিসঙ্গত কারণ কেবল ওভারহেড সেই সময়ের একটি ছোট-ইশ ভগ্নাংশ।

    আপনার উদাহরণস্বরূপ, এটি লক্ষণীয় যে সন্নিবেশ বাছাই এবং টিম সাজানোর উভয়ই ইতিমধ্যে সাজানো তালিকার জন্য সম্পূর্ণ অস্বাভাবিক সময় আচরণ করে beha এর অর্থ হ'ল random.shuffleযদি আপনি আপনার সময় নষ্ট করতে না চান তবে আপনার মধ্যে কিছু সময়ের প্রয়োজন হবে।


1
ইউজেক মানে কি? এটা কি মাইক্রোসেকেন্ডস?
হাসান ইকবাল

2
@ হাসানআইক্বালআনিক হ্যাঁ
Veedrac

@ স্টেফানপোকম্যান কারণ এটি একাধিকবার নমুনা দেওয়ার চেষ্টা করে না।
Veedrac


@ ভাইড্রাক খাঁটি সময় ওভারহেড বিয়োগের বিষয়ে আপনার বক্তব্য বিবেচনা করে, কোনও যুক্তি না দেওয়া হলে timeitএকটি passবিবৃতি কার্যকর করে , যা অবশ্যই কিছুটা সময় নেয়। যদি কোনও যুক্তি দেওয়া হয়, কার্যকর করা passহবে না , তাই 0.014প্রতিটি সময় থেকে কিছু ইউজেক বিয়োগ করা ভুল হবে।
আর্ন

99

আপনি যদি দুটি ব্লক কোড / ফাংশন দ্রুত তুলনা করতে চান তবে আপনি এটি করতে পারেন:

import timeit

start_time = timeit.default_timer()
func1()
print(timeit.default_timer() - start_time)

start_time = timeit.default_timer()
func2()
print(timeit.default_timer() - start_time)

43

আমি টাইমিট ব্যবহার করার সহজ উপায়টি কমান্ড লাইন থেকে পেয়েছি:

দেওয়া টেস্ট.পি :

def InsertionSort(): ...
def TimSort(): ...

টাইমিট এভাবে চালান:

% python -mtimeit -s'import test' 'test.InsertionSort()'
% python -mtimeit -s'import test' 'test.TimSort()'


12
# Генерация целых чисел

def gen_prime(x):
    multiples = []
    results = []
    for i in range(2, x+1):
        if i not in multiples:
            results.append(i)
            for j in range(i*i, x+1, i):
                multiples.append(j)

    return results


import timeit

# Засекаем время

start_time = timeit.default_timer()
gen_prime(3000)
print(timeit.default_timer() - start_time)

# start_time = timeit.default_timer()
# gen_prime(1001)
# print(timeit.default_timer() - start_time)


3

নিম্নলিখিতগুলির প্রতিটিতে একই অভিধান সেটআপ করতে এবং প্রয়োগের সময়টি পরীক্ষা করতে দেয়।

সেটআপ আর্গুমেন্টটি মূলত অভিধানটি সেট আপ করে

নম্বরটি 1000000 বার চালানো হয়। সেটআপ নয় স্ট্যাম্ট

আপনি যখন এটি চালান আপনি দেখতে পাবেন যে সূচীটি পাওয়ার চেয়ে অনেক দ্রুত। আপনি এটি দেখতে একাধিকবার চালাতে পারেন।

কোডটি মূলত অভিধানে সি এর মান পেতে চেষ্টা করে।

import timeit

print('Getting value of C by index:', timeit.timeit(stmt="mydict['c']", setup="mydict={'a':5, 'b':6, 'c':7}", number=1000000))
print('Getting value of C by get:', timeit.timeit(stmt="mydict.get('c')", setup="mydict={'a':5, 'b':6, 'c':7}", number=1000000))

এখানে আমার ফলাফল, আপনার পৃথক হবে।

সূচক দ্বারা: 0.20900007452246427

দ্বারা পেয়ে: 0.54841166886888


আপনি অজগরটির কোন সংস্করণ ব্যবহার করছেন?
এডুয়ার্ডো

3

সময়সীমা হিসাবে একটি আর্গুমেন্ট হিসাবে কেবল আপনার পুরো কোডটি পাস করুন:

import timeit

print(timeit.timeit(

"""   
limit = 10000
prime_list = [i for i in range(2, limit+1)]

for prime in prime_list:
    for elem in range(prime*2, max(prime_list)+1, prime):
        if elem in prime_list:
            prime_list.remove(elem)
"""   
, number=10))


0

বিল্ট ইন টাইমিট মডিউল আইপিথন কমান্ড লাইন থেকে সেরা কাজ করে।

একটি মডিউল থেকে ফাংশন সময় করতে:

from timeit import default_timer as timer
import sys

def timefunc(func, *args, **kwargs):
    """Time a function. 

    args:
        iterations=3

    Usage example:
        timeit(myfunc, 1, b=2)
    """
    try:
        iterations = kwargs.pop('iterations')
    except KeyError:
        iterations = 3
    elapsed = sys.maxsize
    for _ in range(iterations):
        start = timer()
        result = func(*args, **kwargs)
        elapsed = min(timer() - start, elapsed)
    print(('Best of {} {}(): {:.9f}'.format(iterations, func.__name__, elapsed)))
    return result

0

প্যারামিটারগুলি গ্রহণ করে এমন ফাংশন সহ পাইথন আরপিএল দোভাষী কীভাবে ব্যবহার করবেন তার উদাহরণ।

>>> import timeit                                                                                         

>>> def naive_func(x):                                                                                    
...     a = 0                                                                                             
...     for i in range(a):                                                                                
...         a += i                                                                                        
...     return a                                                                                          

>>> def wrapper(func, *args, **kwargs):                                                                   
...     def wrapper():                                                                                    
...         return func(*args, **kwargs)                                                                  
...     return wrapper                                                                                    

>>> wrapped = wrapper(naive_func, 1_000)                                                                  

>>> timeit.timeit(wrapped, number=1_000_000)                                                              
0.4458435332577161                                                                                        

0

আপনি দুটি ফাংশন তৈরি করে তারপরে এর মতো কিছু চালাবেন। লক্ষ্য করুন, আপেলের সাথে আপেলের তুলনা করতে আপনি একই সংখ্যা নির্বাহ / রান চয়ন করতে চান।
এটি পাইথন ৩.7 এর অধীনে পরীক্ষা করা হয়েছিল।

এখানে চিত্র বর্ণনা লিখুন এটি অনুলিপি করার জন্য কোডটি এখানে

!/usr/local/bin/python3
import timeit

def fibonacci(n):
    """
    Returns the n-th Fibonacci number.
    """
    if(n == 0):
        result = 0
    elif(n == 1):
        result = 1
    else:
        result = fibonacci(n-1) + fibonacci(n-2)
    return result

if __name__ == '__main__':
    import timeit
    t1 = timeit.Timer("fibonacci(13)", "from __main__ import fibonacci")
    print("fibonacci ran:",t1.timeit(number=1000), "milliseconds")
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.