python - आप एक स्क्रिप्ट कैसे प्रोफाइल कर सकते हैं?




performance profiling (15)

प्रोजेक्ट यूलर और अन्य कोडिंग प्रतियोगिताओं में अक्सर चलाने के लिए अधिकतम समय होता है या लोग दावा करते हैं कि उनका विशेष समाधान कितना तेज़ चलता है। पायथन के साथ, कभी-कभी दृष्टिकोण कुछ हद तक कमजोर होते हैं - यानी, __main__ को समय कोड __main__

प्रोफाइल करने का एक अच्छा तरीका क्या है कि एक अजगर कार्यक्रम कितना समय लगता है?


कभी जानना चाहते हैं कि पाइथन लिपि क्या कर रही है? निरीक्षण शेल दर्ज करें। निरीक्षण करें शैल आपको ग्लोबल्स को प्रिंट / बदलने देता है और चल रहे स्क्रिप्ट को बाधित किए बिना फ़ंक्शन चलाता है। अब स्वतः पूर्ण और कमांड इतिहास (केवल लिनक्स पर) के साथ।

निरीक्षण करें शैल एक पीडीबी-शैली डीबगर नहीं है।

https://github.com/amoffat/Inspect-Shell

आप उस (और अपने wristwatch) का उपयोग कर सकते हैं।


pprofile

line_profiler (यहां पहले से प्रस्तुत) भी प्रेरित pprofile , जिसे इस प्रकार वर्णित किया गया है:

रेखा-ग्रैन्युलरिटी, थ्रेड-जागरूक निर्धारक और सांख्यिकीय शुद्ध-पायथन प्रोफाइलर

यह line_profiler रूप में लाइन-ग्रैन्युलरिटी प्रदान करता है, शुद्ध पायथन है, जिसे स्टैंडअलोन कमांड या मॉड्यूल के रूप में उपयोग किया जा सकता है, और कॉलग्रिंड-फॉर्मेट फाइल भी उत्पन्न कर सकता है जिसे आसानी से [k|q]cachegrind साथ विश्लेषण किया जा सकता है।

vprof

vprof भी है, एक पायथन पैकेज के रूप में वर्णित है:

[...] चल रहे समय और स्मृति उपयोग जैसे विभिन्न पायथन प्रोग्राम विशेषताओं के लिए समृद्ध और इंटरैक्टिव विज़ुअलाइजेशन प्रदान करते हैं।


इस विषय पर शोध करते समय मैं SnakeViz नामक एक आसान टूल में भाग गया। सांपविज़ एक वेब-आधारित प्रोफाइलिंग विज़ुअलाइजेशन टूल है। इसे स्थापित करना और उपयोग करना बहुत आसान है। मैं जिस सामान्य तरीके से इसका उपयोग करता हूं वह %prun साथ एक स्टेट फ़ाइल उत्पन्न करना है और फिर SnakeViz में विश्लेषण करना है।

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

सबसे अच्छी बात यह है कि आप चार्ट के साथ बातचीत कर सकते हैं। उदाहरण के लिए, ज़ूम इन करने के लिए एक चाप पर क्लिक कर सकते हैं, और अधिक विवरण प्रदर्शित करने के लिए चाप और इसके वंशजों को एक नए सनबर्स्ट के रूप में बढ़ाया जाएगा।


एक अच्छा प्रोफाइलिंग मॉड्यूल line_profiler है (स्क्रिप्ट kernprof.py का उपयोग कर कहा जाता है)। इसे here डाउनलोड किया जा सकता here

मेरी समझ यह है कि सीप्रोफाइल केवल प्रत्येक समारोह में बिताए गए कुल समय के बारे में जानकारी देता है। तो कोड की व्यक्तिगत लाइनों का समय नहीं है। यह वैज्ञानिक कंप्यूटिंग में एक मुद्दा है क्योंकि अक्सर एक सिंगल लाइन में काफी समय लग सकता है। साथ ही, जैसा कि मुझे याद है, cProfile उस समय को पकड़ नहीं पाया जब मैं numpy.dot कह रहा था।


जब मैं सर्वर पर रूट नहीं करता हूं, तो मैं lsprofcalltree.py उपयोग करता lsprofcalltree.py और अपना प्रोग्राम इस तरह चलाता हूं:

python lsprofcalltree.py -o callgrind.1 test.py

फिर मैं qcachegrind जैसे किसी भी कॉलग्रिंड-संगत सॉफ़्टवेयर के साथ रिपोर्ट खोल सकता qcachegrind


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

वर्णनात्मक जानकारी बहुत उपयोगी है। यह आपको उस बिट के लिए कोड दिखाता है जो उपयोगी हो सकता है जब आप अंतर्निहित लाइब्रेरी कॉल से निपट रहे हों। यह आपको बताता है कि कौन सी फाइल और कोड को ढूंढने के लिए कौन सी रेखा है।

यह भी कहना चाहते हैं कि ओपी ने 'प्रोफाइलिंग' कहा लेकिन ऐसा लगता है कि उसका मतलब 'समय' था। ध्यान रखें जब प्रोफाइल प्रोफाइल धीमे हो जाएंगे।


पायथन में cProfile नामक एक प्रोफाइलर शामिल है। यह न केवल कुल चलने वाला समय देता है, बल्कि प्रत्येक समारोह को अलग-अलग करता है, और आपको बताता है कि प्रत्येक फ़ंक्शन को कितनी बार बुलाया गया था, यह निर्धारित करना आसान बनाता है कि आपको अनुकूलन कहां बनाना चाहिए।

आप इसे अपने कोड, या दुभाषिया से, इस तरह से कॉल कर सकते हैं:

import cProfile
cProfile.run('foo()')

और भी उपयोगी रूप से, आप स्क्रिप्ट चलाने पर cProfile का आह्वान कर सकते हैं:

python -m cProfile myscript.py

इसे और भी आसान बनाने के लिए, मैंने 'profile.bat' नामक एक छोटी बैच फ़ाइल बनाई:

python -m cProfile %1

तो मुझे बस इतना करना है:

profile euler048.py

और मुझे यह मिलता है:

1007 function calls in 0.061 CPU seconds

Ordered by: standard name
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.061    0.061 <string>:1(<module>)
 1000    0.051    0.000    0.051    0.000 euler048.py:2(<lambda>)
    1    0.005    0.005    0.061    0.061 euler048.py:2(<module>)
    1    0.000    0.000    0.061    0.061 {execfile}
    1    0.002    0.002    0.053    0.053 {map}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler objects}
    1    0.000    0.000    0.000    0.000 {range}
    1    0.003    0.003    0.003    0.003 {sum}

संपादित करें: पायथन प्रोफाइलिंग नामक पायकॉन 2013 से एक अच्छे वीडियो संसाधन के लिए अद्यतन लिंक।


पायथन में प्रोफाइलिंग को संभालने के लिए एक नया टूल PyVmMonitor है: http://www.pyvmmonitor.com/

इसमें कुछ अनूठी विशेषताएं हैं जैसे कि

  • एक चल रहे (CPython) कार्यक्रम में प्रोफाइलर संलग्न करें
  • याप्पी एकीकरण के साथ प्रोफाइलिंग मांग पर
  • एक अलग मशीन पर प्रोफाइल
  • एकाधिक प्रक्रियाओं का समर्थन (मल्टीप्रोसेसिंग, django ...)
  • लाइव नमूना / सीपीयू व्यू (समय सीमा चयन के साथ)
  • सीप्रोफाइल / प्रोफाइल एकीकरण के माध्यम से निर्धारक प्रोफाइलिंग
  • मौजूदा PStats परिणामों का विश्लेषण करें
  • ओपन डीओटी फाइलें
  • प्रोग्रामेटिक एपीआई एक्सेस
  • विधि या रेखा द्वारा समूह नमूने
  • PyDev एकीकरण
  • PyCharm एकीकरण

नोट: यह वाणिज्यिक है, लेकिन मुक्त स्रोत के लिए मुफ्त है।


मल्टी-थ्रेडेड कोड के बारे में जो शॉ के जवाब के बाद उम्मीद के अनुसार काम नहीं करना है, मुझे लगा कि runcall में runcall विधि केवल self.enable() और self.enable() प्रोफाइल प्रोफाइल कॉल के आसपास कॉल कर रही है, ताकि आप बस ऐसा कर सकें अपने आप के पास और जो भी कोड आप चाहते हैं उसके बीच मौजूदा कोड के साथ न्यूनतम हस्तक्षेप के बीच।


मुझे लगता है कि cProfile प्रोफाइलिंग के लिए बहुत अच्छा है, जबकि kcachegrind परिणामों को देखने के लिए बहुत अच्छा है। फ़ाइल रूपांतरण को संभालने के बीच में pyprof2calltree

python -m cProfile -o script.profile script.py
pyprof2calltree -i script.profile -o script.calltree
kcachegrind script.calltree

आवश्यक उपकरण स्थापित करने के लिए (कम से कम उबंटू पर):

apt-get install kcachegrind
pip install pyprof2calltree

परिणाम:


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

यदि आप थ्रेड को भी प्रोफाइल करना चाहते हैं, तो आप दस्तावेज़ों में threading.setprofile() फ़ंक्शन को देखना चाहेंगे।

आप अपना खुद का threading.Thread भी बना सकते हैं। इसे करने के लिए उप-वर्ग पढ़ें:

class ProfiledThread(threading.Thread):
    # Overrides threading.Thread.run()
    def run(self):
        profiler = cProfile.Profile()
        try:
            return profiler.runcall(threading.Thread.run, self)
        finally:
            profiler.dump_stats('myprofile-%d.profile' % (self.ident,))

और उस मानक के बजाय ProfiledThread कक्षा का उपयोग करें। यह आपको अधिक लचीलापन दे सकता है, लेकिन मुझे यकीन नहीं है कि यह इसके लायक है, खासकर यदि आप तृतीय-पक्ष कोड का उपयोग कर रहे हैं जो आपकी कक्षा का उपयोग नहीं करेगा।


यह इस बात पर निर्भर करेगा कि आप प्रोफाइलिंग से क्या देखना चाहते हैं। सरल समय मीट्रिक (बाश) द्वारा दिया जा सकता है।

time python python_prog.py

यहां तक ​​कि '/ usr / bin / time' '--verbose' ध्वज का उपयोग करके विस्तृत मीट्रिक आउटपुट कर सकता है।

प्रत्येक फ़ंक्शन द्वारा दिए गए समय मीट्रिक की जांच करने के लिए और बेहतर ढंग से समझने के लिए कि फ़ंक्शंस पर कितना समय व्यतीत होता है, आप पाइथन में इनबिल्ट सीप्रोफाइल का उपयोग कर सकते हैं।

प्रदर्शन जैसे अधिक विस्तृत मीट्रिक में जाकर, समय केवल मीट्रिक नहीं है। आप स्मृति, धागे इत्यादि के बारे में चिंता कर सकते हैं
प्रोफाइलिंग विकल्प:
1. line_profiler एक और प्रोफाइलर है जो आमतौर पर टाइमिंग मेट्रिक्स लाइन-बाय-लाइन खोजने के लिए उपयोग किया जाता है।
2. memory_profiler स्मृति उपयोग प्रोफ़ाइल के लिए एक उपकरण है।
3. हेपी (प्रोजेक्ट गुप्पी से) प्रोफाइल कैसे ढेर में ऑब्जेक्ट्स का उपयोग किया जाता है।

ये कुछ आम हैं जिनका मैं उपयोग करता हूं। लेकिन यदि आप और जानना चाहते हैं, तो इस book पढ़ने का प्रयास करें, यह दिमाग में प्रदर्शन के साथ शुरू करने पर एक बहुत अच्छी किताब है। आप साइथन और जेआईटी (जस्ट-इन-टाइम) संकलित पायथन का उपयोग करने पर उन्नत विषयों पर जा सकते हैं।


वर्टाल के source एक बहुत ही उपयोगी वर्ग और सजावट है जो प्रोफाइलिंग कर सकती है (यहां तक ​​कि विशिष्ट तरीकों / कार्यों के लिए भी) बहुत आसान है। आउटपुट को KCacheGrind में बहुत आराम से देखा जा सकता है।


सीप्रोफाइल त्वरित प्रोफाइलिंग के लिए बहुत अच्छा है लेकिन ज्यादातर समय यह त्रुटियों के साथ मेरे लिए समाप्त हो रहा था। फ़ंक्शन रनक्टक्स पर्यावरण और चर को सही ढंग से प्रारंभ करके इस समस्या को हल करता है, उम्मीद है कि यह किसी के लिए उपयोगी हो सकता है:

import cProfile
cProfile.runctx('foo()', None, locals())

https://.com/a/582337/1070617 पर जोड़ने के लिए,

मैंने इस मॉड्यूल को लिखा है जो आपको सीप्रोफाइल का उपयोग करने और आसानी से इसके आउटपुट को देखने की अनुमति देता है। यहां और अधिक: https://github.com/ymichael/cprofilev

$ python -m cprofilev /your/python/program
# Go to http://localhost:4000 to view collected statistics.

यह भी देखें: एकत्रित आंकड़ों को समझने के तरीके पर http://ymichael.com/2014/03/08/profiling-python-with-cprofile.html






time-complexity