2010-06-22 13 views
104

गति और स्मृति की दक्षता के संबंध में एक पाइथन मॉड्यूल और/या फ़ंक्शन के अंदर फ़ंक्शन आयात करने के पेशेवर और विपक्ष क्या हैं?पायथन में, जब आप किसी फ़ंक्शन के अंदर आयात करते हैं तो क्या होता है?

क्या यह कार्य हर बार फिर से आयात करता है, या शायद शुरुआत में केवल एक बार कार्य चल रहा है या नहीं?

+3

कोई गति लाभ नहीं है (कॉलिंग 'आयात' बहुत महंगा है, भले ही मॉड्यूल पहले ही लोड हो)। यदि आप स्पीड लाभ चाहते हैं, तो यह तेज़ है (यदि आप मॉड्यूल को कम से कम 4-5 बार एक्सेस करते हैं) तो मॉड्यूल को स्थानीय वैरिएबल में असाइन करने के लिए केवल अपनी कार्यक्षमता में करते हैं, और फिर उस स्थानीय चर के माध्यम से इसे एक्सेस करें (क्योंकि स्थानीय परिवर्तनीय लुकअप बहुत तेज हैं)। –

+3

(http://us.pycon.org/2010/conference/schedule/event/71/ पर वीडियो में 26:30 तक फास्ट फॉरवर्ड करें यदि आप एक दिलचस्प उदाहरण चाहते हैं कि फ़ंक्शन में हास्यास्पद रूप से खराब आयात कैसे हो सकता है) –

+0

@ निक: यह सुनते समय, ऐसा प्रतीत होता है कि जब भी आप कोशिश कर रहे हैं और जांच कर रहे हैं कि यह आयात किया गया है या नहीं, तब से बार-बार आयात करना धीमा है। क्या आप कह रहे हैं कि फ़ंक्शन के बाहर इसे आयात करें और इसे वैश्विक चर के रूप में सेट करें और फ़ंक्शन के अंदर वैश्विक चर पकड़ लें? –

उत्तर

89

यह फिर से आयात हर बार समारोह चलाया जाता है करता है?

नहीं; या बल्कि, पायथन मॉड्यूल अनिवार्य रूप से हर बार जब वे आयात किए जाते हैं कैश नहीं किया जाता है, तो एक दूसरे (या तीसरे, या चौथे ...) समय वास्तव में उन्हें फिर से पूरे आयात प्रक्रिया के माध्यम से जाने के लिए मजबूर नहीं करता आयात करने।

क्या यह शुरुआत में एक बार आयात करता है कि समारोह चल रहा है या नहीं?

नहीं, यह केवल तभी आयात किया जाता है जब फ़ंक्शन निष्पादित किया जाता है।

लाभ के लिए: यह निर्भर करता है, मुझे लगता है। आप कभी कभी ही एक समारोह चल सकते हैं और मॉड्यूल कहीं और आयातित की जरूरत नहीं है, तो यह फायदेमंद ही नहीं समारोह में आयात हो सकता है। या फिर एक नाम टकराव या अन्य कारण नहीं है अगर आप मॉड्यूल या प्रतीकों मॉड्यूल उपलब्ध हर जगह से नहीं करना चाहते हैं, आप केवल एक विशेष समारोह में आयात कर सकते हैं। (बेशक, वहाँ हमेशा उन मामलों के लिए from my_module import my_function as f है।)

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

+6

विचार की एक ही पंक्ति में, यदि एक सहायक फ़ंक्शन के अंदर आयात टकराया जाता है तो यह एक निर्भरता वैकल्पिक बना सकता है। –

+1

जब मैं अपने लिए लाइब्रेरी मॉड्यूल लिखता हूं तो मैं इसे वैकल्पिक निर्भरताओं के लिए उपयोग करता हूं। मैं पुस्तकालय मॉड्यूल के अंदर प्रत्येक समारोह को कम से कम आयात पर निर्भर करता हूं। – CodeMonkey

9

यह फ़ंक्शन पहली बार निष्पादित होने पर आयात करता है।

सकारात्मक:

  • आयात समारोह वे

विपक्ष पैकेज के आसपास कार्यों को स्थानांतरित करने में

  • आसान इस्तेमाल कर रहे हैं से संबंधित:

    • नहीं देख सकता था इस मॉड्यूल का क्या मॉड्यूल
    पर निर्भर हो सकता है
  • +0

    यदि आप 'grep import/path/to/module' जैसे कुछ करते हैं तो यह आपको आयात करने वाले सभी मॉड्यूल दिखाएगा। – dashaxiong

    2

    यह पहली बार फ़ंक्शन कहलाता है जब यह आयात करता है।

    मैं इस तरह से ऐसा करने की कल्पना कर सकता हूं अगर मेरे पास आयातित मॉड्यूल में कोई फ़ंक्शन था जो बहुत ही कम इस्तेमाल होता है और केवल आयात की आवश्यकता होती है। हालांकि, दूर-दूर तक दिखता है, हालांकि ...

    5

    फ़ंक्शन के अंदर आयात करना प्रभावी रूप से मॉड्यूल को प्रभावी रूप से आयात करेगा .. पहली बार फ़ंक्शन चलाया जाएगा।

    इसे जितना तेज़ आयात करना चाहिए, चाहे आप इसे शीर्ष पर आयात करते हैं, या जब फ़ंक्शन चलाया जाता है। डीएफ में आयात करने के लिए यह आमतौर पर एक अच्छा कारण नहीं है। पेशेवरों? यदि फ़ंक्शन नहीं कहा जाता है तो यह आयात नहीं किया जाएगा .. यह वास्तव में एक उचित कारण है यदि आपके मॉड्यूल को केवल एक निश्चित मॉड्यूल स्थापित करने की आवश्यकता होती है यदि वे आपके विशिष्ट कार्यों का उपयोग करते हैं ...

    यदि यह है ऐसा नहीं है कि आप ऐसा कर रहे हैं, यह लगभग निश्चित रूप से एक भाग्यशाली विचार है।

    32

    बहुत पहले समय आप import goo कहीं से भी (अंदर या बाहर एक समारोह), goo.py (या अन्य आयात योग्य फार्म) भरी हुई है और sys.modules['goo'] मॉड्यूल वस्तु इस प्रकार बनाया को तैयार है। कार्यक्रम के एक ही भाग के भीतर कोई भविष्य का आयात (फिर से, चाहे किसी फ़ंक्शन के अंदर या बाहर) sys.modules['goo'] देखें और इसे उचित दायरे में goo पर बैरनाम करें। ताना लुकअप और नाम बाध्यकारी बहुत तेज संचालन हैं।

    मान लिया जाये कि बहुत पहले import पूरी तरह से वैसे भी कार्यक्रम के समय से अधिक परिशोधित हो जाता है, "उचित दायरे" मॉड्यूल-स्तर हो रही है, आदि goo.this में से प्रत्येक के उपयोग, goo.that है, जिसका अर्थ है दो dict लुकअप - goo के लिए एक और के लिए एक विशेषता नाम। इसे "फ़ंक्शन लेवल" होने के कारण फ़ंक्शन के प्रति रन (यहां तक ​​कि डिक्शनरी लुकअप भाग से भी तेज़) की एक अतिरिक्त स्थानीय-परिवर्तनीय सेटिंग का भुगतान किया जाता है, लेकिन प्रत्येक goo.this के लिए एक स्पोकल लुकअप (स्थानीय-चरणीय लुकअप के लिए इसका आदान-प्रदान) (आदि) पहुंच, मूल रूप से इस तरह के लुकअप लेने के समय को कम करने।

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

    यह अभी भी एक अनुकूलन है जो बहुत चरम स्थितियों में केवल सार्थक है, और ऐसे कई अन्य हैं जिन्हें मैं इस तरह से माइक्रोसेकंड को निचोड़ने की कोशिश करने से पहले विचार करता हूं।

    +0

    यह अनुकूलन वास्तव में कभी सार्थक नहीं है - मॉड्यूल पहले से लोड होने पर भी 'आयात' को कॉल करने के अविश्वसनीय व्यय के लिए कोई भी तेज़ स्थानीय चरणीय पहुंच नहीं होगी। यह देखने के लिए जांच कर रहा है कि एक मॉड्यूल लोड किया गया है या नहीं, यह एक बहुत महंगा ऑपरेशन है (कुछ वैश्विक शब्दकोश लुकअप के सापेक्ष)। –

    +2

    पहली बार मॉड्यूल आयात करना महंगा है। एक खाली स्क्रिप्ट बनाम एक को चलाने का प्रयास करें जिसमें केवल 'आयात स्ट्रिंग, itertools, अंश, हेपैक, पुनः, सरणी, bisect, संग्रह, गणित, ओएस' शामिल है। पहले 180 एमएस औसत और दूसरा 230 एमएस लेता है। तो यह शुरुआत करने वालों के लिए microseconds नहीं है। यह मिलीसेकंड के दसियों (शायद डिस्क का उपयोग होता है?)। यह छोटी स्क्रिप्ट के लिए महत्वपूर्ण है जो कई बार चलाता है (जैसे वेब अनुरोधों की सेवा करना)। –

    +0

    @EvgeniSergeev उस मामले में आपके पास आमतौर पर एक सर्वर चल रहा है, इस प्रकार यह बार-बार फिर से आयात नहीं करेगा –

    3

    क्या मैं सामान्य रूप से सुझाव दे सकता हूं कि पूछने के बजाय, "क्या एक्स मेरे प्रदर्शन में सुधार करेगा?" आप यह निर्धारित करने के लिए प्रोफाइलिंग का उपयोग करते हैं कि आपका प्रोग्राम वास्तव में अपना समय व्यतीत कर रहा है और उसके बाद अनुकूलन लागू करें जहां आपको सबसे अधिक लाभ मिलेगा?

    और फिर आप यह सुनिश्चित करने के लिए प्रोफाइलिंग का उपयोग कर सकते हैं कि आपके अनुकूलन ने आपको भी लाभान्वित किया है।

    +2

    मैं इसके साथ सहमत हूं, यह एक जिज्ञासा प्रश्न था। मैं सोच रहा था कि कैसे पाइथन की आयात विधि अधिक विस्तार से काम करती है, समय से पहले प्रदर्शन बढ़ाने की कोशिश करने से ज्यादा। धन्यवाद हालांकि :) –

    +2

    आह। खैर, मुझे उम्मीद है कि यहां उत्कृष्ट उत्तरों ने आपकी जिज्ञासा को संतुष्ट कर दिया है! Effbot में कुछ जानकारी है जो आपके लिए उपयोग की जा सकती है: http://effbot.org/zone/import-confusion.htm "पाइथन एक मॉड्यूल आयात करने के लिए क्या करता है?" पर स्क्रॉल करें – gomad

    +0

    जानकारी के लिए धन्यवाद, उत्तर बहुत उत्कृष्ट और मददगार रहे हैं। –

    संबंधित मुद्दे

     संबंधित मुद्दे