2010-08-17 17 views
21

ऐसा इसलिए है क्योंकि हमें कक्षा लोड करना चाहिए (उदाहरण के लिए string द्वारा), उदाहरण बनाएं, फिर उचित विधि, पैक पैरामीटर खोजें, और फिर विधि का आह्वान करें? इसलिए किसी ऑब्जेक्ट पर स्पष्ट विधि आमंत्रण के बजाय इन परिचालनों पर अधिकतर समय व्यतीत किया जाता है, है ना?प्रतिबिंब धीमा क्यों है?

+3

आधुनिक जेडीके/जेवीएम कार्यान्वयन में यह आपको लगता है कि यह इतना धीमा नहीं है। – Roman

उत्तर

28

जब भी आप प्रतिबिंब का उपयोग करते हैं तो आप जो भी कदम उठाते हैं उसे सत्यापित करने की आवश्यकता होती है। उदाहरण के लिए, जब आप किसी विधि का आह्वान करते हैं, तो उसे यह जांचने की आवश्यकता होती है कि लक्ष्य वास्तव में विधि की घोषणा का एक उदाहरण है, भले ही आपको तर्कों की सही संख्या मिल गई हो, चाहे प्रत्येक तर्क सही प्रकार का हो, आदि

इनलाइनिंग या अन्य प्रदर्शन चाल की बिल्कुल संभावना नहीं है।

यदि आपको नाम से प्रकार या विधियां मिल रही हैं, तो यह एक साधारण मानचित्र लुकअप को शामिल करने के लिए सबसे अच्छा है - जो हर बार जब आप इसे JIT समय पर निष्पादित करते हैं, तो इसे निष्पादित किया जाएगा।

असल में ऐसा करने के लिए बहुत कुछ है। हालांकि, प्रतिबिंब यह बहुत तेज हो गया है ... यदि आप इसे बहुत धीमा कर रहे हैं, तो आप इसे अत्यधिक इस्तेमाल कर सकते हैं।

+1

एक और सूक्ष्म मुद्दा यह है कि प्रतिबिंब का उपयोग करते समय, obfuscators को कम आक्रामक होने की आवश्यकता हो सकती है, जिसके परिणामस्वरूप कम लाभ होते हैं।(कई obfuscator निर्माताओं का दावा है कि obfuscation प्रदर्शन लाभ के साथ ही आईपी संरक्षण और पदचिह्न कमी प्रदान करता है। देखें, उदाहरण के लिए, [इस लेख] (http://www.devx.com/wireless/Article/28989/1954)।) –

+0

है यह सिर्फ invocations कि विशेष रूप से धीमी है? अन्य प्रतिबिंब उपयोगों के बारे में क्या है जैसे गुणों की गणना करना, घोषित करने का प्रकार, गेटर/सेटर विधियां आदि प्राप्त करना? क्या ये भी धीमी हैं? –

+0

@zespri: ठीक है, "धीमा" आमतौर पर किसी और चीज के सापेक्ष होता है - यह कहना मुश्किल है कि गुणों की गणना करना "धीमा" है क्योंकि यह प्रतिबिंब के बाहर कुछ भी नहीं किया गया है - जबकि "विधि का आह्वान करें" या "फ़ील्ड मान प्राप्त करें" बहुत अधिक है सीधे से प्रतिबिंब के साथ धीमी। क्या प्रतिबिंब-केवल संचालन आपके ऐप की तुलना में धीमे होते हैं, यह एक अलग मामला है ... –

6

ऊपर जॉन स्कीट का जवाब देने के लिए एक परिशिष्ट के रूप में (मैं टिप्पणी करने के लिए सक्षम होने के लिए में और अधिक प्रतिष्ठा की जरूरत है।):

प्रतिबिंब CPU संसाधनों उपलब्ध होने पर निर्भर है; अगर आपको धीमे होने पर आपके आवेदन में समस्या है, तो प्रतिबिंब कुछ हल नहीं करेगा, बस इसे धीमा कर दें।

तरह जावा ही है, प्रतिबिंब किसी भी अधिक धीमी गति से नहीं है - यह एक पुरानी अफवाह की अधिक है;)

+0

प्रतिबिंब धीमा नहीं होना सच नहीं है। तीन vairable वर्ग के लिए एक toString() हाथ कोडित toString की तुलना में मेरे लिए पचास प्रतिशत धीमी है। (मैं ओपनजेडीके 8 का उपयोग कर रहा हूं) –

2

जब आप एक विधि कॉल, यदि आप वैध तर्क के साथ तो कर रहे हैं पता करने की जरूरत, पर एक मान्य वस्तु, रिटर्न प्रकार क्या है, और निष्पादित करने के लिए बाइटकोड क्या है। जब कोड में सटीक विधि निर्दिष्ट होती है, तो जावा इस सामग्री को तुरंत समझ सकता है और वास्तव में विधि को निष्पादित करने के लिए आगे बढ़ सकता है।

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

पॉलिमॉर्फिक विधि कॉल इन दो चरम सीमाओं के बीच कहीं भी हो सकती है। आप नहीं जानते कि रन टाइम तक कौन सी विधि का आह्वान करना है, लेकिन कम से कम आप विधि के नाम, तर्क और वापसी प्रकार के बारे में सुनिश्चित हो सकते हैं। जितना अधिक आप निष्पादित करने के तरीके के बारे में जानते हैं, उतना ही जावा रन रन पर काम करने से बच सकता है।

यह साबित करता है कि प्रतिबिंब धीमा है, लेकिन यह वास्तव में "धीमा" नहीं है। यदि आपको प्रतिबिंब या बहुलक तरीकों की आवश्यकता है, तो उनका उपयोग करें, और बाद में "धीमी" के निर्णय को बचाएं।

0

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

अन्य मामलों में, जैसे जांच करना कि लक्ष्य एक ही प्रकार या हस्ताक्षर है, यह बिल्कुल धीमा है।

ईवेंट यह धीमा है, लेकिन यह बॉक्स कार्यान्वयन के बाहर महत्वपूर्ण है ...: डी।

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