क्या जावा स्टैटिक कॉल्स नॉन-स्टैटिक कॉल्स की तुलना में कम या ज्यादा महंगी हैं?


जवाबों:


74

पहला: आपको प्रदर्शन के आधार पर स्थिर बनाम गैर-स्थिर का विकल्प नहीं बनाना चाहिए।

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

तीसरा: स्थिर बनाम गैर स्थिर आसपास के मिथक के ज्यादा या तो पर बहुत पुरानी JVMs (जो अनुकूलन कि हॉटस्पॉट करता है के पास कहीं भी नहीं किया हो) आधारित होते हैं, या सी के बारे में कुछ याद सामान्य ज्ञान ++ (जो एक गतिशील कॉल का उपयोग करता है में एक अधिक स्मृति का उपयोग एक स्थिर कॉल की तुलना में)।


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

2
@AaronDigulla - क्या होगा अगर मैंने आपको बताया कि मैं यहां आया हूं क्योंकि मैं अभी समय से पहले अनुकूलन कर रहा हूं, लेकिन समय से पहले, लेकिन जब मुझे वास्तव में इसकी आवश्यकता है? आपने मान लिया कि ओपी समय से पहले अनुकूलन करना चाहता है, लेकिन आप जानते हैं कि यह साइट थोड़े वैश्विक है ... ठीक है? मैं असभ्य नहीं बनना चाहता, लेकिन कृपया अगली बार इस तरह की चीजों को ग्रहण न करें।
Dalibor Filus

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

6
Downvoted। इस सवाल का जवाब नहीं है। प्रदर्शन लाभ के बारे में पूछा गया प्रश्न। इसने डिजाइन सिद्धांतों पर राय नहीं मांगी।
कोलम भंडाल

4
अगर मैंने एक तोते को प्रशिक्षित करने के लिए कहा कि "समय से पहले दूध पिलाना सभी बुराई की जड़ है" तो मुझे ऐसे लोगों से 1000 वोट मिलेंगे जो तोते के रूप में प्रदर्शन के बारे में ज्यादा जानते हैं।
रगोम

62

चार साल बाद...

ठीक है, इस प्रश्न को एक बार और हमेशा के लिए निपटाने की उम्मीद में, मैंने एक बेंचमार्क लिखा है जिसमें दिखाया गया है कि विभिन्न प्रकार की कॉल (आभासी, गैर-आभासी, स्थिर) एक दूसरे से तुलना कैसे करती हैं।

मैंने इसे विचारधारा पर चलाया , और यही मुझे मिला:

(पुनरावृत्तियों की बड़ी संख्या बेहतर है।)

    Success time: 3.12 memory: 320576 signal:0
  Name          |  Iterations
    VirtualTest |  128009996
 NonVirtualTest |  301765679
     StaticTest |  352298601
Done.

जैसा कि अपेक्षित था, वर्चुअल मेथड कॉल्स सबसे धीमी हैं, नॉन-वर्चुअल मैथड कॉल्स तेज़ हैं, और स्टैटिक मेथड कॉल्स और भी तेज़ हैं।

मुझे उम्मीद नहीं थी कि मतभेद इतने स्पष्ट होंगे: वर्चुअल मेथड कॉल्स को गैर-वर्चुअल मेथड कॉल्स की आधी से कम गति से चलाने के लिए मापा गया था, जो बदले में स्टैटिक कॉल्स की तुलना में पूरे 15% धीमी गति से चलने के लिए मापा गया था । यही माप दिखाता है; वास्तविक अंतर वास्तव में थोड़ा अधिक स्पष्ट होना चाहिए, क्योंकि प्रत्येक आभासी, गैर-आभासी और स्थिर विधि कॉल के लिए, मेरे बेंचमार्किंग कोड में एक पूर्णांक चर को बढ़ाने के लिए एक अतिरिक्त निरंतर ओवरहेड होता है, जो बूलियन चर की जाँच करता है, और यदि सही नहीं है तो लूपिंग।

मुझे लगता है कि परिणाम सीपीयू से सीपीयू और जेवीएम से जेवीएम तक अलग-अलग होंगे, इसलिए इसे आजमाएं और देखें कि आप क्या कर रहे हैं:

import java.io.*;

class StaticVsInstanceBenchmark
{
    public static void main( String[] args ) throws Exception
    {
        StaticVsInstanceBenchmark program = new StaticVsInstanceBenchmark();
        program.run();
    }

    static final int DURATION = 1000;

    public void run() throws Exception
    {
        doBenchmark( new VirtualTest( new ClassWithVirtualMethod() ), 
                     new NonVirtualTest( new ClassWithNonVirtualMethod() ), 
                     new StaticTest() );
    }

    void doBenchmark( Test... tests ) throws Exception
    {
        System.out.println( "  Name          |  Iterations" );
        doBenchmark2( devNull, 1, tests ); //warmup
        doBenchmark2( System.out, DURATION, tests );
        System.out.println( "Done." );
    }

    void doBenchmark2( PrintStream printStream, int duration, Test[] tests ) throws Exception
    {
        for( Test test : tests )
        {
            long iterations = runTest( duration, test );
            printStream.printf( "%15s | %10d\n", test.getClass().getSimpleName(), iterations );
        }
    }

    long runTest( int duration, Test test ) throws Exception
    {
        test.terminate = false;
        test.count = 0;
        Thread thread = new Thread( test );
        thread.start();
        Thread.sleep( duration );
        test.terminate = true;
        thread.join();
        return test.count;
    }

    static abstract class Test implements Runnable
    {
        boolean terminate = false;
        long count = 0;
    }

    static class ClassWithStaticStuff
    {
        static int staticDummy;
        static void staticMethod() { staticDummy++; }
    }

    static class StaticTest extends Test
    {
        @Override
        public void run()
        {
            for( count = 0;  !terminate;  count++ )
            {
                ClassWithStaticStuff.staticMethod();
            }
        }
    }

    static class ClassWithVirtualMethod implements Runnable
    {
        int instanceDummy;
        @Override public void run() { instanceDummy++; }
    }

    static class VirtualTest extends Test
    {
        final Runnable runnable;

        VirtualTest( Runnable runnable )
        {
            this.runnable = runnable;
        }

        @Override
        public void run()
        {
            for( count = 0;  !terminate;  count++ )
            {
                runnable.run();
            }
        }
    }

    static class ClassWithNonVirtualMethod
    {
        int instanceDummy;
        final void nonVirtualMethod() { instanceDummy++; }
    }

    static class NonVirtualTest extends Test
    {
        final ClassWithNonVirtualMethod objectWithNonVirtualMethod;

        NonVirtualTest( ClassWithNonVirtualMethod objectWithNonVirtualMethod )
        {
            this.objectWithNonVirtualMethod = objectWithNonVirtualMethod;
        }

        @Override
        public void run()
        {
            for( count = 0;  !terminate;  count++ )
            {
                objectWithNonVirtualMethod.nonVirtualMethod();
            }
        }
    }

    static final PrintStream devNull = new PrintStream( new OutputStream() 
    {
        public void write(int b) {}
    } );
}

यह ध्यान देने योग्य है कि यह प्रदर्शन अंतर केवल उस कोड पर लागू होता है जो पैरामीटर रहित विधियों को लागू करने के अलावा और कुछ नहीं करता है। जो भी कोड आपके पास इनवोकेशन के बीच है वह अंतरों को कम करेगा, और इसमें पैरामीटर पासिंग शामिल है। दरअसल, स्थैतिक और गैर-व्यावसायिक कॉल के बीच 15% अंतर को संभवतः इस तथ्य से पूर्ण रूप से समझाया गया है कि thisसूचक को स्थैतिक विधि से पारित नहीं होना है। तो, यह केवल कॉल की एक छोटी सी राशि ले जाएगा जिसमें विभिन्न प्रकार के कॉल के बीच के अंतर के लिए तुच्छ सामान होता है, जो कि शुद्ध प्रभाव नहीं होने के बिंदु पर पतला होता है।

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


7
'वर्चुअल' एक C ++ टर्म है। जावा में कोई वर्चुअल तरीके नहीं हैं। साधारण तरीके हैं, जो रनटाइम-पॉलीमॉर्फिक हैं, और स्थिर या अंतिम तरीके हैं, जो नहीं हैं।
झेन्या

16
@levgen हाँ, किसी के लिए जिसका दृष्टिकोण भाषा के आधिकारिक उच्च-स्तरीय अवलोकन जितना संकीर्ण है, यह ठीक वैसा ही है जैसा आप कहते हैं। लेकिन निश्चित रूप से उच्च-स्तरीय अवधारणाओं को अच्छी तरह से स्थापित निम्न-स्तरीय तंत्रों का उपयोग करके कार्यान्वित किया जाता है जो कि जावा अस्तित्व में आने से बहुत पहले आविष्कार किए गए थे, और आभासी विधियाँ उनमें से एक हैं। यदि आप हुड के नीचे सिर्फ एक छोटा सा रूप लेते हैं, तो आप तुरंत देखेंगे कि यह ऐसा है: docs.oracle.com/javase/specs/jvms/se7/html/…
माइक

13
समय से पहले अनुकूलन के बारे में अनुमान लगाए बिना प्रश्न का उत्तर देने के लिए धन्यवाद। बहुत बढ़िया जवाब।
vegemite4me

3
हां, ठीक यही मेरा मतलब है। वैसे भी मैं सिर्फ अपनी मशीन पर परीक्षण चलाता था। घबराहट के अलावा आप ऐसे बेंचमार्क के लिए उम्मीद कर सकते हैं कि गति में कोई अंतर नहीं है: VirtualTest | 488846733 -- NonVirtualTest | 480530022 -- StaticTest | 484353198मेरे OpenJDK इंस्टॉलेशन पर। FTR: यह और भी सही है अगर मैं finalसंशोधक को हटा दूं। Btw। मुझे terminateमैदान बनाना था volatile, वरना टेस्ट खत्म नहीं होता।
मार्टिन

4
FYI करें, मैं एंड्रॉयड 6 चल Nexus 5 की बजाय आश्चर्य की बात परिणाम प्राप्त: VirtualTest | 12451872 -- NonVirtualTest | 12089542 -- StaticTest | 8181170। इतना ही नहीं मेरी नोटबुक पर OpenJDK 40x अधिक पुनरावृत्तियों को करने का प्रबंधन करता है, स्थैतिक परीक्षण में हमेशा लगभग 30% कम थ्रूपुट होता है। यह एक एआरटी विशिष्ट घटना हो सकती है, क्योंकि मुझे एंड्रॉइड 4.4 टैबलेट पर एक अपेक्षित परिणाम मिलता है:VirtualTest | 138183740 -- NonVirtualTest | 142268636 -- StaticTest | 161388933
मार्टन

46

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

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


वे संभावित कारण हैं कि एक स्थिर कॉल क्यों तेज हो सकता है क्या आप मुझे उन कारणों की व्याख्या कर सकते हैं?
JavaTechnical

6
@JavaTechnical: इस सवाल का जवाब उन कारणों को बताते हैं - कोई अधिभावी (जो साधन आप हर बार उपयोग करने के लिए कार्यान्वयन बाहर काम करने की जरूरत नहीं है और आप इनलाइन कर सकते हैं) और आप आप एक पर विधि कॉल कर रहे हैं कि क्या जांच करने के लिए की जरूरत नहीं है अशक्त संदर्भ।
जॉन स्कीट

6
@JavaTechnical: मुझे समझ नहीं आया। मैंने आपको केवल ऐसी चीजें दी हैं जो एक इनलाइनिंग अवसर के साथ-साथ स्थिर तरीकों के लिए गणना / जांच करने की आवश्यकता नहीं हैं। नहीं काम कर रही है एक प्रदर्शन लाभ। समझने के लिए क्या बचा है?
1922 में जॉन स्कीट

क्या स्टैटिक वैरिएबल गैर-स्टैटिक वैरिएबल की तुलना में तेजी से प्राप्त होते हैं?
JavaTechnical

1
@JavaTechnical: वैसे तो प्रदर्शन करने के लिए कोई अशक्तता जांच नहीं है - लेकिन अगर JIT कंपाइलर उस चेक को हटा सकता है (जो कि संदर्भ-विशिष्ट होगा), तो मैं बहुत अंतर की उम्मीद नहीं करूंगा। स्मृति कैश में है या नहीं जैसी चीजें अधिक महत्वपूर्ण होंगी।
जॉन स्कीट

18

यह संकलक / वीएम विशिष्ट है।

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

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

हालाँकि मैंने देखा है कि यह अनुकूलन निम्नलिखित स्थिति में पर्याप्त प्रदर्शन बढ़ाता है:

  • कोई मेमोरी एक्सेस के साथ एक बहुत ही सरल गणितीय गणना करने वाला तरीका
  • एक तंग आंतरिक लूप में विधि प्रति सेकंड लाखों बार आह्वान की जा रही है
  • सीपीयू बाध्य आवेदन जहां प्रदर्शन के हर बिट मायने रखती है

यदि उपरोक्त आप पर लागू होता है, तो यह परीक्षण के लायक हो सकता है।

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


14

जैसा कि पिछले पोस्टरों ने कहा है: यह एक समयपूर्व अनुकूलन की तरह लगता है।

हालांकि, एक अंतर है (इस तथ्य से एक हिस्सा है कि गैर-स्थैतिक इनवोकेशन को ऑपरेंड स्टैक पर एक कैली-ऑब्जेक्ट के अतिरिक्त पुश की आवश्यकता होती है):

चूंकि स्थैतिक विधियों को ओवरराइड नहीं किया जा सकता है, इसलिए स्थैतिक विधि कॉल के लिए रनटाइम में कोई वर्चुअल लुकअप नहीं होगा । इसके परिणामस्वरूप कुछ परिस्थितियों में एक अंतर दिखाई दे सकता है।

बाइट-कोड स्तर पर अंतर यह है कि एक गैर-स्थैतिक विधि कॉल के माध्यम से किया जाता है INVOKEVIRTUAL, INVOKEINTERFACEया INVOKESPECIALजबकि एक स्थिर विधि कॉल के माध्यम से किया जाता है INVOKESTATIC


2
एक निजी उदाहरण विधि, हालांकि, (कम से कम आमतौर पर) का उपयोग करके लागू किया जाता है invokespecialक्योंकि यह आभासी नहीं है।
मार्क पीटर्स

आह, दिलचस्प, मैं केवल कंस्ट्रक्टरों के बारे में सोच सकता था, यही कारण है कि मैंने इसे छोड़ दिया! धन्यवाद! (अद्यतन उत्तर)
aioobe

2
JVM ऑप्टिमाइज़ करेगा यदि एक प्रकार का त्वरित है। यदि B A को बढ़ाता है, और B का कोई उदाहरण त्वरित नहीं किया गया है, तो A पर विधि कॉलों को वर्चुअल टेबल लुकअप की आवश्यकता नहीं होगी।
स्टीव कू ने

13

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


यह नथुना था! shreevatsa.wordpress.com/2008/05/16/...
ShreevatsaR

क्या आप आगे बताएंगे कि "" समय से पहले अनुकूलन सभी बुराई की जड़ है ""?
user2121

सवाल यह था कि "क्या कोई प्रदर्शन किसी एक या दूसरे तरीके से लाभान्वित होता है?", और यह वास्तव में उस प्रश्न का उत्तर देता है।
डीजेकवरवर्थ

13

7 साल बाद ...

मेरे पास माइक नाकिस के परिणामों में बहुत बड़ा विश्वास नहीं है क्योंकि वे हॉटस्पॉट के अनुकूलन से संबंधित कुछ सामान्य मुद्दों को संबोधित नहीं करते हैं। मैंने JMH का उपयोग करते हुए बेंचमार्क इंस्ट्रूमेंट किया है और एक उदाहरण विधि का ओवरहेड पाया है जो कि मेरी मशीन बनाम स्टेटिक कॉल पर लगभग 0.75% है। यह देखते हुए कि कम ओवरहेड मुझे लगता है कि सबसे विलंबता संवेदनशील संचालन को छोड़कर यह एक आवेदन डिजाइन में सबसे बड़ी चिंता नहीं है। मेरे जेएमएच बेंचमार्क से सारांश परिणाम निम्नानुसार हैं;

java -jar target/benchmark.jar

# -- snip --

Benchmark                        Mode  Cnt          Score         Error  Units
MyBenchmark.testInstanceMethod  thrpt  200  414036562.933 ± 2198178.163  ops/s
MyBenchmark.testStaticMethod    thrpt  200  417194553.496 ± 1055872.594  ops/s

आप यहाँ Github पर कोड देख सकते हैं;

https://github.com/nfisher/svsi

बेंचमार्क अपने आप में बहुत सरल है लेकिन मृत कोड उन्मूलन और निरंतर तह को कम करना है। संभवतः अन्य अनुकूलन हैं जो मैंने याद किया / अनदेखा किया है और ये परिणाम जेवीएम रिलीज़ और ओएस के अनुसार भिन्न हो सकते हैं।

package ca.junctionbox.svsi;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;

class InstanceSum {
    public int sum(final int a, final int b) {
        return a + b;
    }
}

class StaticSum {
    public static int sum(final int a, final int b) {
        return a + b;
    }
}

public class MyBenchmark {
    private static final InstanceSum impl = new InstanceSum();

    @State(Scope.Thread)
    public static class Input {
        public int a = 1;
        public int b = 2;
    }

    @Benchmark
    public void testStaticMethod(Input i, Blackhole blackhole) {
        int sum = StaticSum.sum(i.a, i.b);
        blackhole.consume(sum);
    }

    @Benchmark
    public void testInstanceMethod(Input i, Blackhole blackhole) {
        int sum = impl.sum(i.a, i.b);
        blackhole.consume(sum);
    }
}

1
विशुद्ध रूप से शैक्षणिक रुचि यहां। मैं किसी भी संभावित लाभ के बारे में उत्सुक हूं कि इस तरह के माइक्रो-ऑप्टिमाइज़ेशन ops/sमुख्य रूप से एआरटी वातावरण (उदाहरण के उपयोग, कम। फ़ाइल फ़ाइल आकार आदि) के अलावा अन्य मैट्रिक्स पर हो सकते हैं । क्या आप किसी भी अपेक्षाकृत सरल उपकरण / तरीके के बारे में जानते हैं जो इन अन्य मैट्रिक्स को बेंचमार्क करने का प्रयास कर सकता है?
रयान थॉमस

हॉटस्पॉट के आंकड़े बताते हैं कि क्लासपैथ में इंस्टेंससम का कोई एक्सटेंशन नहीं है। एक अन्य वर्ग जोड़ने की कोशिश करें जो InstanceSum का विस्तार करता है और विधि को ओवरराइड करता है।
मिलन

12

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

1.) स्टेटिक तरीके बहुरूपी नहीं हैं, इसलिए जेवीएम के पास निष्पादन के लिए वास्तविक कोड खोजने के लिए कम निर्णय हैं। यह हॉटस्पॉट की आयु में एक म्यूट पॉइंट है, क्योंकि हॉटस्पॉट इंस्टेंस विधि कॉल को अनुकूलित करेगा जिसमें केवल एक कार्यान्वयन साइट है, इसलिए वे समान प्रदर्शन करेंगे।

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


5

इसमें अंतर हो सकता है, और यह किसी भी विशेष कोड कोड के लिए रास्ता हो सकता है, और यह JVM के मामूली रिलीज के साथ बदल सकता है।

यह निश्चित रूप से 97% छोटी क्षमता का हिस्सा है जिसे आपको भूल जाना चाहिए


2
गलत। आप कुछ भी नहीं मान सकते। यह फ्रंट-एंड यूआई के लिए आवश्यक एक तंग लूप हो सकता है जो यूआई कैसे "तड़क" पर एक बड़ा अंतर बना सकता है। उदाहरण के लिए, TableViewलाखों अभिलेखों के लिए एक खोज ।
त्रयी

0

सिद्धांत रूप में, कम महंगा है।

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

हालाँकि, मैंने इसका परीक्षण नहीं किया है।


1
@R। बेमरोज, स्थैतिक आरंभीकरण का इस सवाल से क्या लेना-देना है?
Kirk Woll

@ किर्क वूल: क्योंकि स्टैटिक इनिशियलाइजेशन पहली बार क्लास रेफर किए जाने के बाद किया जाता है ... जिसमें पहले स्टैटिक मेथड कॉल को शामिल किया जाता है।
पावरलॉर्ड

@R। Bemrose, यकीन है, के रूप में शुरू करने के लिए VM में कक्षा लोड हो रहा है। एक गैर-अनुक्रमिक, आईएमओ की तरह लगता है।
Kirk Woll

0

जॉन नोट्स के रूप में, स्थैतिक तरीकों को ओवरराइड नहीं किया जा सकता है, इसलिए बस एक स्थिर विधि को लागू करना हो सकता है - एक पर्याप्त भोले जावा रनटाइम पर - एक इंस्टेंस विधि को लागू करने की तुलना में तेज़ ।

लेकिन फिर, यहां तक ​​कि आप उस बिंदु पर हैं जहां आप अपने डिजाइन को कुछ नैनोसेकंड को बचाने के लिए गड़बड़ करने के बारे में परवाह करते हैं, कि बस एक और सवाल उठता है: क्या आपको खुद को ओवरराइड करने की विधि की आवश्यकता होगी? यदि आप एक नैनो विधि से इधर-उधर जाने के लिए एक स्थिर विधि में एक इंस्टेंस विधि बनाने के लिए अपना कोड बदलते हैं, और फिर अपने चारों ओर अपना स्वयं का डिस्पैचर लागू करते हैं, तो आपका निश्चित रूप से निर्मित की तुलना में कम कुशल होने वाला है आपके जावा रनटाइम में पहले से ही।


-2

मैं यहां अन्य महान उत्तरों में जोड़ना चाहूंगा कि यह आपके प्रवाह पर भी निर्भर करता है, उदाहरण के लिए:

Public class MyDao {

   private String sql = "select * from MY_ITEM";

   public List<MyItem> getAllItems() {
       springJdbcTemplate.query(sql, new MyRowMapper());
   };
};

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

Public class MyDao {

   private static RowMapper myRowMapper = new MyRowMapper();
   private String sql = "select * from MY_ITEM";

   public List<MyItem> getAllItems() {
       springJdbcTemplate.query(sql, myRowMapper);
   };
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.