2010-01-26 24 views
38

स्मृति और समय के मामले में, क्या यह विधि स्थिर है?स्थिर तरीके अधिक कुशल हैं?

+1

अपने प्रश्न का उत्तर देने के लिए: हाँ, लेकिन आपको इसे कभी भी ध्यान में नहीं रखना चाहिए। एल बुशकिन के जवाब देखें। –

+0

पूरी तरह से प्रश्न का खुलासा किया। ऐसा लगता है कि आप एक विधि स्थिर बनाने की वास्तविक प्रक्रिया का जिक्र कर रहे थे।;) रिफैक्टरिंग टूल्स इस प्रक्रिया को तेज़ी से बनाते हैं! पिछले पैराग्राफ के लिए –

उत्तर

75

आमतौर पर हाँ, "इस" संदर्भ को पारित करने की कोई आवश्यकता नहीं है। यह संदर्भ ईसीएक्स रजिस्टर में पारित किया गया है, इसलिए कोई अतिरिक्त स्टैक स्पेस आवश्यक नहीं है। रजिस्टर पहले ही सेट हो चुका है यदि आप एक ही कक्षा के उदाहरण विधि से कॉल करते हैं, तो कोई बचत नहीं होगी। लेकिन यह विधि किसी अन्य वर्ग में होने पर x86 CPU कोर पर दबाव को राहत देने में मदद कर सकती है, x86 में बहुत सारे रजिस्ट्रार नहीं हैं। एक मापनीय perf सुधार देखना बहुत दुर्लभ होगा।

मैं ऐसे वर्ग के धार्मिक तरीके से चिह्नित करता हूं जो आवृत्ति सदस्यों को स्थिर के रूप में उपयोग नहीं करते हैं। मैं स्थैतिक कीवर्ड द्वारा प्रदान किए गए अंतर्निहित अनुबंध को महत्व देता हूं: "यह विधि ऑब्जेक्ट स्थिति को म्यूटेट नहीं करती है।"

+15

+1 - यह वास्तव में यहां मायने रखता है और यह 'स्थैतिक' अमूल्य बनाता है। –

+0

आधुनिक x86 cpus रजिस्टर aliasing का उपयोग करें। –

+0

@ कोनराड, अपवॉट के लिए धन्यवाद। हम एक जैसे देखते हैं। –

7

यदि आप वैसे भी (SomeStaticMethod(obj, "abc", 123);) में पास करने जा रहे हैं, तो वास्तव में नहीं। आप केवल पॉलिमॉर्फिज्म के बिना परिदृश्य में एक स्थिर विधि का उपयोग कर सकते हैं, और ऐसे मामलों में यह संभावना है कि सरल गुणों जैसी चीजें वैसे भी रेखांकित की गई होंगी।

उपयोग वस्तुओं "स्वाभाविक रूप से" (obj.SomeMethod("abc",123);) - कोड सरल रखने के लिए, और प्रोफ़ाइल प्रदर्शन के मुद्दों को खोजने के लिए - यह बहुत उदाहरण और स्थिर के बीच अंतर में होने की जब तक आप कुछ बहुत चल रहे हैं संभावना नहीं तंग loops। कुछ परिदृश्य हैं जहां इससे कोई फर्क पड़ता है, लेकिन वे बहुत विशिष्ट हैं।

49

यदि आपको उस वर्ग से किसी भी राज्य की जानकारी की आवश्यकता नहीं है, तो उसे एक विधि स्थैतिक बनाना चाहिए।

आप बहुरूपता की परवाह नहीं करते हैं, तो आप या तो उदाहरण के लिए या सिर्फ वर्ग उदाहरण सदस्यों लेते हैं और उन्हें तर्कों के रूप विधि को पारित करने के लिए तय करने के बाद स्थिर के रूप में किसी भी विधि लिख सकते हैं। आपको पर क्या विचार करना चाहिए, यह है कि सिंटैक्स प्राकृतिक है, चाहे कोड समझने में आसान हो और सार्थक हो, और इसी तरह।

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

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

आप विधि के अर्थशास्त्र का विश्लेषण करने और उस आधार पर स्थैतिक/उदाहरण निर्णय लेने के बेहतर हैं।

+2

यह मेरी समझ है कि आईएल कोड जो माइक्रोसॉफ्ट सी # उत्पन्न करता है, सभी उदाहरण विधियों के लिए आभासी प्रेषण (कॉलवर्ट) का उपयोग करता है चाहे वह आभासी है या नहीं, यहां तक ​​कि मुहरबंद कक्षाओं के लिए भी। यह कॉलवर्ट की अंतर्निहित नल-जांच का उपयोग करना है। अन्यथा, एक शून्य जांच को कोड करना होगा, क्योंकि सीएलआर को शून्य उदाहरण पर इंस्टेंस विधि को कॉल करने में कोई समस्या नहीं है। –

+0

हां, लेकिन सैद्धांतिक रूप से, जिटर कुछ मामलों में गैर-आभासी तरीकों को रेखांकित कर सकता है। यह सीलबंद कक्षाओं जैसे मामलों में 'कॉलवर्ट' को प्रतिस्थापित करने के लिए कुछ स्थिर विश्लेषण भी कर सकता है, और इसी तरह। मुझे यकीन नहीं है कि यह वास्तव में यह कितना हद तक करता है, लेकिन यह संभव है। – LBushkin

+7

ग्रेट जेफ एटवुड उद्धृत करने के लिए - आप किसी भी भाषा में फोरट्रान लिख सकते हैं। – Nick

1

अंतर ज्यादातर मामलों में लापरवाह है, लेकिन स्थैतिक अधिक प्रभावशाली है।

निम्न चरणों को एक स्थिर विधि कॉल में परहेज कर रहे हैं:

  1. जांच की जा रही है कि वस्तु संदर्भ (यह) अशक्त नहीं है।
  2. आभासी प्रेषण तालिका पर सही विधि ढूँढना।
  3. स्टैक पर ऑब्जेक्ट संदर्भ रखना।
0

मुझे लगता है कि किसी दिए गए वर्ग में मुझे लिखने वाली कई उपयोगिता विधियों को केवल कक्षा में कुछ डेटा सदस्यों की आवश्यकता है, या कोई भी नहीं। इन मामलों में, मैं उन विधियों को (स्टैंड-अलोन) स्थिर विधियों के रूप में लिखता हूं, जो उन्हें आवश्यक कुछ डेटा आइटमों में गुजरते हैं।

यदि वे विशेष रूप से सामान्य और अन्य कक्षाओं के लिए उपयोगी हैं, तो मैं उन्हें भी सार्वजनिक कर सकता हूं।

3

इस तरह के कई प्रश्न हैं। स्थिर तरीके तेज/धीमी हैं? वर्चुअल फ़ंक्शंस तेज़/धीमे हैं? क्या मैं ++ से तेज़/धीमा हूं? (सत्य) के दौरान (;;) तेज/धीमी है?

यह कुछ सॉफ्टवेयर और tuning it की पकड़ हो रही सार्थक है। यह आपको उन चीजों की अच्छी समझ देगा जो वास्तव में सॉफ्टवेयर प्रदर्शन को प्रभावित करते हैं।

तो फिर तुम यह है कि इस तरह के सवालों के जवाब देखेंगे (ज्यादातर समय) है कि यह नगण्य है।

यदि मैं सामान्यीकृत कर सकता हूं, तो मेरे अनुभव में सॉफ़्टवेयर धीमा करने वाली चीजें, निर्दोष दिखने वाले कोड की रेखाओं का उपयोग होती हैं, लेकिन जिनकी समय खपत कल्पना की जा सकती है उससे बड़ा परिमाण का आदेश हो सकती है। चूंकि वे निर्दोष दिखते हैं, इसलिए वे कोड को देखकर विश्वसनीय रूप से नहीं मिल सकते हैं। उदाहरण: यह सुनिश्चित करने के लिए कि वे मौजूद हैं, बड़े डेटा संरचनाओं को बार-बार आवंटित करना, प्रारंभ करना और हटाना। इंटरनेशनलिंग स्ट्रिंग्स जो होने की आवश्यकता नहीं है। अधिसूचना-शैली प्रोग्रामिंग जो एक बड़ी डेटा संरचना में विधि कॉल के बड़े पैमाने पर कैस्केड में एक संपत्ति की एक साधारण सेटिंग को बदल सकती है। सरल ओ (एन^2) ऑपरेशंस जो कभी समस्या नहीं होती थी, सिवाय इसके कि एन बड़ा हो गया। यह सोचकर कि (< बी) समय की एक ही अवधि लेता है कि क्या ए और बी चींटियों या बड़ी कक्षाएं हैं। यह "निर्दोष दिखने का समय गुणा" का अतिक्रमण की कई परतों पर एक जटिल प्रभाव पड़ता है, इसलिए मेरे अनुभव में बड़े सॉफ्टवेयर को इसके साथ झुकाया जाता है।

5

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

एक विधि स्थिर होना चाहिए।

दूसरी ओर वर्चुअल विधियों (अतिसंवेदनशील) को कॉलर को तथाकथित vtable में सटीक कार्यान्वयन को देखने की आवश्यकता होती है। कंपाइलर को बहुत छोटी विधियों को रेखांकित करने से रोकने के अलावा (सरल संपत्ति एक्सेसर्स को अक्सर रेखांकित किया जाता है) लुकअप कुछ चक्र लेता है।

फिर भी, वर्चुअल विधियां सी #/सीएलआर में उपलब्ध गतिशील प्रेषण का सबसे तेज़ तरीका है। प्रतिनिधि और प्रतिबिंब से बहुत तेज।

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