आमतौर पर मैं शेल कमांड का उपयोग करता हूं time
। मेरा उद्देश्य परीक्षण करना है कि क्या डेटा छोटा, मध्यम, बड़ा या बहुत बड़ा सेट है, कितना समय और स्मृति उपयोग होगा।
ऐसा करने के लिए लिनक्स या सिर्फ अजगर के लिए कोई उपकरण?
जवाबों:
पर एक नज़र डालें timeit , अजगर प्रोफाइलर और pycallgraph । " स्नेपविज़ " का उल्लेख करके नीचे टिप्पणीnikicc
पर एक नज़र अवश्य डालें । यह आपको प्रोफाइलिंग डेटा का एक और दृश्य देता है जो मददगार हो सकता है।
def test():
"""Stupid test function"""
lst = []
for i in range(100):
lst.append(i)
if __name__ == '__main__':
import timeit
print(timeit.timeit("test()", setup="from __main__ import test"))
# For Python>=3.5 one can also write:
print(timeit.timeit("test()", globals=locals()))
अनिवार्य रूप से, आप इसे एक स्ट्रिंग पैरामीटर के रूप में अजगर कोड पास कर सकते हैं, और यह निर्दिष्ट समय में चलेगा और निष्पादन समय प्रिंट करेगा। डॉक्स से महत्वपूर्ण बिट्स :
timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None)
Timer
दिए गए कथन, सेटअप कोड और टाइमर फ़ंक्शन के साथ एक उदाहरण बनाएं और संख्या निष्पादन केtimeit
साथ इसकी विधि चलाएं । वैकल्पिक ग्लोबल्स तर्क एक नेमस्पेस निर्दिष्ट करता है जिसमें कोड निष्पादित करना है।
... तथा:
Timer.timeit(number=1000000)
मुख्य बयान के समय संख्या निष्पादित। यह एक बार सेटअप स्टेटमेंट को निष्पादित करता है, और फिर मुख्य स्टेटमेंट को कई बार निष्पादित करने में लगने वाला समय लौटाता है, एक फ्लोट के रूप में सेकंड में मापा जाता है। तर्क लूप के माध्यम से कई बार होता है, एक मिलियन तक डिफ़ॉल्ट होता है। मुख्य कथन, सेटअप स्टेटमेंट और उपयोग किए जाने वाले टाइमर फ़ंक्शन को कंस्ट्रक्टर को पास किया जाता है।नोट: डिफ़ॉल्ट रूप से, समय के दौरान
timeit
अस्थायी रूप से बंद हो जाता हैgarbage collection
। इस दृष्टिकोण का लाभ यह है कि यह स्वतंत्र समय को अधिक तुलनीय बनाता है। यह नुकसान यह है कि जीसी मापा जा रहा फ़ंक्शन के प्रदर्शन का एक महत्वपूर्ण घटक हो सकता है। यदि हां, तो जीसी को सेटअप स्ट्रिंग में पहले स्टेटमेंट के रूप में फिर से सक्षम किया जा सकता है । उदाहरण के लिए:
timeit.Timer('for i in xrange(10): oct(i)', 'gc.enable()').timeit()
रूपरेखा आप एक दे देंगे ज्यादा क्या हो रहा है के बारे में विस्तृत विचार। यहां आधिकारिक डॉक्स से "त्वरित उदाहरण" दिया गया है :
import cProfile
import re
cProfile.run('re.compile("foo|bar")')
जो आपको देगा:
197 function calls (192 primitive calls) in 0.002 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.001 0.001 <string>:1(<module>)
1 0.000 0.000 0.001 0.001 re.py:212(compile)
1 0.000 0.000 0.001 0.001 re.py:268(_compile)
1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset)
1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset)
4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction)
3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile)
इन दोनों मॉड्यूल से आपको अंदाजा हो सकता है कि आपको अड़चनों की तलाश कहाँ करनी है।
इसके अलावा, के उत्पादन के साथ पकड़ पाने के लिए profile
, इस पोस्ट पर एक नज़र है
नोट pycallgraph को फरवरी 2018 से आधिकारिक तौर पर छोड़ दिया गया है । दिसंबर 2020 तक यह अजगर 3.6 पर काम कर रहा था। जब तक कि कैसे पायथन प्रोफाइल को उजागर करता है, तब तक इसमें कोई कोर बदलाव नहीं होते हैं, हालांकि इसे एक उपयोगी उपकरण बना रहना चाहिए।
यह मॉड्यूल निम्न की तरह कॉलगर्ल बनाने के लिए ग्राफविज़ का उपयोग करता है:
आप आसानी से देख सकते हैं कि किन रास्तों का इस्तेमाल सबसे ज्यादा बार किया गया है। आप या तो उन्हें pycallgraph API का उपयोग करके बना सकते हैं, या पैक स्क्रिप्ट का उपयोग कर सकते हैं:
pycallgraph graphviz -- ./mypythonscript.py
ओवरहेड हालांकि काफी विचारणीय है। तो पहले से ही लंबे समय से चल रही प्रक्रियाओं के लिए, ग्राफ बनाने में कुछ समय लग सकता है।
मैं समय-समय पर एक साधारण डेकोरेटर का उपयोग करता हूं
def st_time(func):
"""
st decorator to calculate the total time of a func
"""
def st_func(*args, **keyArgs):
t1 = time.time()
r = func(*args, **keyArgs)
t2 = time.time()
print "Function=%s, Time=%s" % (func.__name__, t2 - t1)
return r
return st_func
timeit
मॉड्यूल, धीमी और अजीब था तो मैं यह लिखा:
def timereps(reps, func):
from time import time
start = time()
for i in range(0, reps):
func()
end = time()
return (end - start) / reps
उदाहरण:
import os
listdir_time = timereps(10000, lambda: os.listdir('/'))
print "python can do %d os.listdir('/') per second" % (1 / listdir_time)
मेरे लिए, यह कहता है:
python can do 40925 os.listdir('/') per second
यह एक आदिम प्रकार का बेंचमार्किंग है, लेकिन यह काफी अच्छा है।
मैं आमतौर पर यह time ./script.py
देखने के लिए एक त्वरित करता हूं कि इसमें कितना समय लगता है। यह आपको स्मृति नहीं दिखाता है, लेकिन कम से कम डिफ़ॉल्ट के रूप में नहीं। आप /usr/bin/time -v ./script.py
स्मृति उपयोग सहित बहुत सी जानकारी प्राप्त करने के लिए उपयोग कर सकते हैं ।
/usr/bin/time
साथ यह कमांड -v
कई डिस्ट्रो में डिफ़ॉल्ट रूप में उपलब्ध नहीं है, स्थापित किया जाना है। sudo apt-get install time
में डेबियन, ubuntu, आदि pacman -S time
अभिलेखागार
आपकी सभी मेमोरी जरूरतों के लिए मेमोरी प्रोफाइलर।
https://pypi.python.org/pypi/memory_profiler
एक पाइप स्थापित करें:
pip install memory_profiler
पुस्तकालय आयात करें:
import memory_profiler
उस आइटम में एक डेकोरेटर जोड़ें जिसे आप प्रोफाइल करना चाहते हैं:
@profile
def my_func():
a = [1] * (10 ** 6)
b = [2] * (2 * 10 ** 7)
del b
return a
if __name__ == '__main__':
my_func()
कोड निष्पादित करें:
python -m memory_profiler example.py
आउटपुट प्राप्त करें:
Line # Mem usage Increment Line Contents
==============================================
3 @profile
4 5.97 MB 0.00 MB def my_func():
5 13.61 MB 7.64 MB a = [1] * (10 ** 6)
6 166.20 MB 152.59 MB b = [2] * (2 * 10 ** 7)
7 13.61 MB -152.59 MB del b
8 13.61 MB 0.00 MB return a
उदाहरण डॉक्स से हैं, जो ऊपर दिए गए हैं।
पर एक नज़र डालें नाक और उसके प्लगइन्स से एक है, पर यह एक विशेष रूप से।
एक बार स्थापित होने के बाद, नाक आपके रास्ते में एक स्क्रिप्ट है, और आप एक निर्देशिका में कॉल कर सकते हैं जिसमें कुछ अजगर स्क्रिप्ट हैं:
$: nosetests
यह वर्तमान निर्देशिका में सभी अजगर फाइलों में दिखेगा और किसी भी फ़ंक्शन को निष्पादित करेगा जो इसे एक परीक्षण के रूप में पहचानता है: उदाहरण के लिए, यह परीक्षण के रूप में इसके नाम में test_ शब्द के साथ किसी भी फ़ंक्शन को पहचानता है।
तो आप बस एक अजगर स्क्रिप्ट बना सकते हैं, जिसे test_yourfunction.py कहा जाता है और उसमें कुछ इस तरह लिखा जाता है:
$: cat > test_yourfunction.py
def test_smallinput():
yourfunction(smallinput)
def test_mediuminput():
yourfunction(mediuminput)
def test_largeinput():
yourfunction(largeinput)
फिर दौड़ना पड़ेगा
$: nosetest --with-profile --profile-stats-file yourstatsprofile.prof testyourfunction.py
और प्रोफ़ाइल फ़ाइल पढ़ने के लिए, इस अजगर लाइन का उपयोग करें:
python -c "import hotshot.stats ; stats = hotshot.stats.load('yourstatsprofile.prof') ; stats.sort_stats('time', 'calls') ; stats.print_stats(200)"
nose
हॉटशॉट पर निर्भर करता है। यह अब पायथन 2.5 के बाद से बनाए नहीं रखा गया है और केवल "विशेष उपयोग के लिए" रखा गया है
केयरफुल होना timeit
बहुत धीमा है, यह मेरे मध्यम प्रोसेसर पर 12 सेकंड लेता है बस आरंभ करने के लिए (या शायद फ़ंक्शन चलाएं)। आप इस स्वीकार किए गए उत्तर का परीक्षण कर सकते हैं
def test():
lst = []
for i in range(100):
lst.append(i)
if __name__ == '__main__':
import timeit
print(timeit.timeit("test()", setup="from __main__ import test")) # 12 second
साधारण बात के लिए मैं time
इसके बजाय अपने पीसी पर उपयोग करूंगा , यह परिणाम लौटाता है0.0
import time
def test():
lst = []
for i in range(100):
lst.append(i)
t1 = time.time()
test()
result = time.time() - t1
print(result) # 0.000000xxxx
timeit
शोर को औसत करने के लिए, अपने कार्य को कई बार चलाता है । दोहराए जाने की संख्या एक विकल्प है, इस प्रश्न पर स्वीकृत जवाब में बेंचमार्क को बाद के समय या बाद के भाग में देखें।
snakeviz
cProfile के लिए इंटरैक्टिव दर्शक
https://github.com/jiffyclub/snakeviz/
cProfile का उल्लेख https://stackoverflow.com/a/1593034/895245 पर किया गया था और स्नेकविज़ का उल्लेख एक टिप्पणी में किया गया था , लेकिन मैं इसे और उजागर करना चाहता था।
यह केवल cprofile
/ pstats
आउटपुट को देखकर प्रोग्राम के प्रदर्शन को डीबग करना बहुत कठिन है , क्योंकि वे केवल बॉक्स से बाहर प्रति फ़ंक्शन कुल समय हो सकते हैं।
हालाँकि, हमें वास्तव में सामान्य रूप से एक नेस्टेड दृश्य को देखना पड़ता है जिसमें प्रत्येक कॉल के स्टैक के निशान होते हैं जो वास्तव में मुख्य बाधाओं को आसानी से ढूंढ सकते हैं।
और यह वही है जो स्नेकविज़ अपने डिफ़ॉल्ट "आइकिकल" दृश्य के माध्यम से प्रदान करता है।
पहले आपको cProfile डेटा को एक बाइनरी फ़ाइल में डंप करना होगा, और फिर आप उस पर स्नेकविज़ कर सकते हैं
pip install -u snakeviz
python -m cProfile -o results.prof myscript.py
snakeviz results.prof
यह एक URL प्रिंट करने के लिए प्रिंट करता है जिसे आप अपने ब्राउज़र पर खोल सकते हैं, जिसमें वांछित आउटपुट होता है जो इस तरह दिखता है:
और आप तब कर सकते हैं:
अधिक प्रोफ़ाइल उन्मुख प्रश्न: आप एक पायथन स्क्रिप्ट कैसे प्रोफाइल कर सकते हैं?
यदि आप समय के लिए बॉयलरप्लेट कोड नहीं लिखना चाहते हैं और परिणामों का विश्लेषण करना आसान है, तो बेंचमार्क पर एक नज़र डालें । साथ ही यह पिछले रनों के इतिहास को बचाता है, इसलिए विकास के दौरान समान फ़ंक्शन की तुलना करना आसान है।
# pip install benchmarkit
from benchmarkit import benchmark, benchmark_run
N = 10000
seq_list = list(range(N))
seq_set = set(range(N))
SAVE_PATH = '/tmp/benchmark_time.jsonl'
@benchmark(num_iters=100, save_params=True)
def search_in_list(num_items=N):
return num_items - 1 in seq_list
@benchmark(num_iters=100, save_params=True)
def search_in_set(num_items=N):
return num_items - 1 in seq_set
benchmark_results = benchmark_run(
[search_in_list, search_in_set],
SAVE_PATH,
comment='initial benchmark search',
)
टर्मिनल के लिए प्रिंट और अंतिम रन के लिए डेटा के साथ शब्दकोशों की सूची देता है। कमांड लाइन प्रविष्टि भी उपलब्ध है।
यदि आप बदलते हैं N=1000000
और फिर से दौड़ते हैं
python -m cProfile -o results.prof myscript.py
। Oputput फ़ाइल को बहुत अच्छी तरह से एक ब्राउज़र में स्नेविज़ नामक प्रोग्राम द्वारा प्रस्तुत किया जा सकता हैsnakeviz results.prof