क्या जावा में इनलाइन फ़ंक्शन की अवधारणा है, या इसकी जगह कुछ और है? यदि है, तो इसका उपयोग कैसे किया जाता है? मैंने सुना है कि public
, static
और final
विधियाँ इनलाइन फ़ंक्शन हैं। क्या हम अपना इनलाइन फ़ंक्शन बना सकते हैं?
क्या जावा में इनलाइन फ़ंक्शन की अवधारणा है, या इसकी जगह कुछ और है? यदि है, तो इसका उपयोग कैसे किया जाता है? मैंने सुना है कि public
, static
और final
विधियाँ इनलाइन फ़ंक्शन हैं। क्या हम अपना इनलाइन फ़ंक्शन बना सकते हैं?
जवाबों:
जावा में, अनुकूलन आमतौर पर जेवीएम स्तर पर किया जाता है। रनटाइम के दौरान, JVM इनलाइन निर्धारित करने के लिए कुछ "जटिल" विश्लेषण करता है। यह आक्रामक इनलाइनिंग हो सकता है, और हॉटस्पॉट जेवीएम वास्तव में गैर-अंतिम तरीकों को इनलाइन कर सकता है।
जावा कंपाइलर लगभग कभी भी किसी भी तरीके की कॉल को इनलाइन नहीं करता है (जेवीएम रनटाइम के दौरान वह सब करता है)। वे इनलाइन संकलन समय स्थिरांक (जैसे अंतिम स्थैतिक आदिम मान) करते हैं। लेकिन तरीके नहीं।
अधिक संसाधनों के लिए:
विकी: OpenJDK में इनलाइनिंग , पूरी तरह से आबाद नहीं है लेकिन इसमें उपयोगी चर्चाओं के लिंक हैं।
नहीं, जावा में कोई इनलाइन फ़ंक्शन नहीं है । हां, आप किसी सार्वजनिक वर्ग में रखे जाने पर कोड में कहीं भी सार्वजनिक स्थैतिक विधि का उपयोग कर सकते हैं। जावा कंपाइलर स्थैतिक या अंतिम विधि पर इनलाइन विस्तार कर सकता है , लेकिन इसकी गारंटी नहीं है।
आमतौर पर ऐसे कोड ऑप्टिमाइज़ेशन कंपाइलर द्वारा JVM / JIT / HotSpot के साथ संयोजन में किए जाते हैं, जो कोड सेगमेंट में बहुत बार उपयोग किए जाते हैं। इसके अलावा अन्य अनुकूलन अवधारणाएं जैसे रजिस्टर घोषणाएं जावा में ज्ञात नहीं हैं।
अनुकूलन को जावा में घोषणा के द्वारा मजबूर नहीं किया जा सकता है, लेकिन संकलक और जेआईटी द्वारा किया जाता है। कई अन्य भाषाओं में, ये घोषणाएं अक्सर केवल संकलक संकेत होती हैं (आप प्रोसेसर से अधिक रजिस्टर पैरामीटर घोषित कर सकते हैं, बाकी को अनदेखा किया जाता है)।
संकलक के लिए स्थिर, अंतिम या निजी java विधियों की घोषणा भी संकेत है। आपको इसका उपयोग करना चाहिए, लेकिन कोई गारंटी नहीं। जावा प्रदर्शन गतिशील है, स्थिर नहीं है। क्लास लोडिंग के कारण सिस्टम पर पहला कॉल हमेशा धीमा होता है। अगली कॉलें तेज़ होती हैं, लेकिन मेमोरी और रनटाइम के आधार पर सबसे आम कॉल को रनिंग सिस्टम के साथ ऑप्टिमाइज़ किया जाता है, इसलिए रनटाइम के दौरान एक सर्वर तेज़ हो सकता है!
final
जेआईटी इनलाइनिंग पर कोई प्रभाव न
जावा मैन्युअल रूप से सुझाव देने का एक तरीका प्रदान नहीं करता है कि एक विधि को इनलाइन किया जाना चाहिए। जैसा कि @notnoop टिप्पणियों में कहता है, इनलाइनिंग आमतौर पर JVM द्वारा निष्पादन समय पर की जाती है।
jdk.internal.vm.annotation.ForceInline
आपने जो ऊपर कहा वह सही है। कभी-कभी अंतिम तरीकों को इनलाइन के रूप में बनाया जाता है, लेकिन जावा में इनलाइन फ़ंक्शन को स्पष्ट रूप से बनाने का कोई अन्य तरीका नहीं है।
final
भी कोई फर्क नहीं पड़ता है कि क्या विधि इनबिल्ट है या नहीं।
वास्तविक जीवन उदाहरण:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
फिर अन्य वर्गों में, यदि कोड समाप्त हो गया है तो मैं बाहर निकल सकता हूं। यदि मैं EXPIRED_ON चर को दूसरी कक्षा से संदर्भित करता हूं, तो निरंतर बाइट कोड के लिए इनलाइन है, जिससे कोड की सभी जगहों को ट्रैक करना बहुत मुश्किल हो जाता है जो समाप्ति की तारीख की जांच करता है। हालाँकि, यदि अन्य वर्ग isExpired () विधि को लागू करते हैं, तो वास्तविक विधि को कहा जाता है, जिसका अर्थ है कि एक हैकर isExpired विधि को दूसरे के साथ बदल सकता है जो हमेशा गलत रिटर्न देता है।
मैं मानता हूं कि किसी कंपाइलर को स्टैटिक फाइनल मेथड इन क्लास के लिए मजबूर करना बहुत अच्छा होगा जो इसे रेफर करता है। उस स्थिति में, आपको नियंत्रण वर्ग भी शामिल करने की आवश्यकता नहीं है, क्योंकि रनटाइम में इसकी आवश्यकता नहीं होगी।
मेरे शोध से, यह नहीं किया जा सकता है। शायद कुछ Obfuscator उपकरण ऐसा कर सकते हैं, या, आप संकलन करने से पहले स्रोतों को संपादित करने के लिए अपनी निर्माण प्रक्रिया को संशोधित कर सकते हैं।
यह सिद्ध करने के लिए कि क्या नियंत्रण वर्ग से विधि संकलन के दौरान दूसरी कक्षा में इनलाइन की जाती है, क्लास क्लास में नियंत्रण वर्ग के बिना अन्य वर्ग को चलाने का प्रयास करें।
खैर, ऐसे तरीके हैं जिन्हें जावा में "इनलाइन" तरीके कहा जा सकता है, लेकिन जेवीएम पर निर्भर करता है। संकलित करने के बाद, यदि विधि का मशीन कोड 35 बाइट से कम है, तो इसे तुरंत इनलाइन विधि में स्थानांतरित किया जाएगा, यदि विधि का मशीन कोड 325 बाइट से कम है, तो इसे एक इनलाइन विधि में स्थानांतरित किया जा सकता है, यह jmm पर निर्भर करता है।
इसलिए, ऐसा लगता है कि वहाँ कुछ भी नहीं है, लेकिन आप इस वर्कअराउंड का उपयोग अमरूद या एक समतुल्य फंक्शन क्लास कार्यान्वयन के लिए कर सकते हैं, क्योंकि यह क्लास बेहद सरल, पूर्व है:
assert false : new com.google.common.base.Function<Void,String>(){
@Override public String apply(Void input) {
//your complex code go here
return "weird message";
}}.apply(null);
हां, यह मृत कोड है कि केवल एक जटिल कोड ब्लॉक बनाने के लिए ({} के भीतर) कुछ विशिष्ट ऐसा करने के लिए कैसे करें जो हमें इसके लिए कोई भी विधि बनाने में परेशान न करे, एके इनलाइन!