जावा में Instof का उपयोग करने का प्रदर्शन प्रभाव


314

मैं एक एप्लिकेशन पर काम कर रहा हूं और एक डिजाइन दृष्टिकोण में instanceofऑपरेटर का बहुत भारी उपयोग शामिल है । जबकि मुझे पता है कि ओओ डिजाइन आमतौर पर उपयोग करने से बचने की कोशिश करता है instanceof, यह एक अलग कहानी है और यह सवाल विशुद्ध रूप से प्रदर्शन से संबंधित है। मैं सोच रहा था कि क्या कोई प्रदर्शन प्रभाव है? बस के रूप में उपवास के रूप में है ==?

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

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

क्या instanceofकिसी तरह से JVM द्वारा अनुकूलित किया जा सकता है इससे तेज? मैं जावा से चिपके रहना चाहता हूं लेकिन ऐप का प्रदर्शन महत्वपूर्ण है। यह अच्छा होगा यदि कोई व्यक्ति इस सड़क से पहले उतर गया हो तो कुछ सलाह दे सकता है। क्या मैं बहुत ज्यादा नाइटपैकिंग कर रहा हूं या अनुकूलन के लिए गलत चीज पर ध्यान केंद्रित कर रहा हूं?


81
मुझे लगता है कि प्रश्न का बिंदु, हालांकि, सबसे अच्छा ओओ अभ्यास के प्रश्न को अलग करना था, और प्रदर्शन की जांच करना था।
डेव एल।

3
@ डी। एल। आम तौर पर मैं सहमत होता हूं, लेकिन ओपी का उल्लेख है कि वह कुछ सामान्य अनुकूलन तकनीकों की तलाश कर रहा है और उसे यकीन नहीं है कि उसकी समस्या 'इंस्टाफॉफ़' से संबंधित है। मुझे लगता है कि यह कम से कम 'सही' डिजाइन का उल्लेख करने के लायक है, इसलिए वह दोनों विकल्पों को प्रोफाइल कर सकता है।
प्रोग्रामर

51
उह ... सभी उत्तर प्रश्न के बिंदु से क्यों चूकते हैं और अनुकूलन के बारे में वही पुरानी नुथ बयानबाजी की आपूर्ति करते हैं? आपका प्रश्न इस बात को लेकर है कि क्या वर्ग वस्तु को जाँचने की तुलना में यह महत्वपूर्ण है / आश्चर्यजनक रूप से धीमा ==, और मैंने पाया है कि यह नहीं है।
गब्बी

3
इंस्टाॅफ और कास्टिंग का प्रदर्शन काफी अच्छा है। मैंने समस्या के विभिन्न तरीकों के बारे में जावा 7 में कुछ समय पोस्ट किया है: stackoverflow.com/questions/16320014/…
Wheezil

जवाबों:


268

आधुनिक JVM / JIC संकलक ने पारंपरिक रूप से "धीमे" संचालन के अधिकांश हिट को हटा दिया है, जिसमें इंस्टाफॉफ, अपवाद हैंडलिंग, प्रतिबिंब, आदि शामिल हैं।

जैसा कि डोनाल्ड नुथ ने लिखा है, "हमें छोटी क्षमताओं के बारे में भूलना चाहिए, 97% समय के बारे में कहना चाहिए: समय से पहले अनुकूलन सभी बुराई की जड़ है।" Instof का प्रदर्शन शायद एक मुद्दा नहीं होगा, इसलिए जब तक आप सुनिश्चित नहीं करते कि समस्या है, तब तक विदेशी वर्कअराउंड के साथ आने में अपना समय बर्बाद न करें।


13
आधुनिक JVM / JIC .. आप कृपया यह उल्लेख कर सकते हैं कि किस जावा संस्करण से ये आशावाद कवर किया गया है?
रविशा

138
हमेशा कोई ऐसा व्यक्ति होता है, जो प्रदर्शन के दौरान नुथ का हवाला देता है ... भूल जाता है, कि नुथ ने यह भी कहा (एक ही लेख में) "स्थापित इंजीनियरिंग में एक 12% सुधार आसानी से प्राप्त होता है, इसे कभी भी मामूली नहीं माना जाता है और मेरा मानना ​​है कि एक ही दृष्टिकोण है सॉफ्टवेयर इंजीनियरिंग में प्रबल होना चाहिए ", लगभग उनका सारा काम एल्गोरिदम की दक्षता के बारे में था और उन्होंने विधानसभा में (इंटर आलिया) को बेहतर प्रदर्शन प्राप्त करने के लिए एल्गोरिदम लिखा था।
मेह

4
यहाँ एक तरफ है, लेकिन try { ObjT o = (ObjT)object } catch (e) { no not one of these }किसी भी तेजी से धीमी होगी ??
15

35
यदि "ऑब्जेक्ट" ओबजटी का एक उदाहरण है, तो कास्टिंग करना एक इंस्टॉफ़ करने की तुलना में थोड़ा तेज़ है, लेकिन मेरे त्वरित परीक्षण में पाया गया अंतर 10,000,000 पुनरावृत्तियों पर 10-20ms था। यदि "ऑब्जेक्ट" एक ओबीजेट नहीं है, हालांकि, अपवाद को पकड़ना 3000x से अधिक धीमा था - उदाहरण के लिए 31,000ms बनाम ~ 10ms से अधिक।
स्टीव

19
किसी भी "संदर्भ" के बिना इस तरह के एक मजबूत तर्क, पूरी तरह से बेकार है क्योंकि सिर्फ राय है।
मार्कोरोसी

278

पहुंच

मैंने विभिन्न कार्यान्वयनों का मूल्यांकन करने के लिए एक बेंचमार्क कार्यक्रम लिखा :

  1. instanceof कार्यान्वयन (संदर्भ के रूप में)
  2. एक अमूर्त वर्ग और @Overrideएक परीक्षण विधि के माध्यम से केंद्रित वस्तु
  3. स्वयं के प्रकार के कार्यान्वयन का उपयोग करना
  4. getClass() == _.class कार्यान्वयन

मैंने 100 वार्मअप कॉल, मापने के तहत 1000 पुनरावृत्तियों और 10 कांटे के साथ बेंचमार्क चलाने के लिए जेएमएच का उपयोग किया । इसलिए प्रत्येक विकल्प को 10 000 बार मापा गया था, जो कि मेरे मैकबुक प्रो पर पूरे मैकमार्क 10.12.4 और जावा 1.8 के साथ चलाने के लिए 12:18:57 लेता है। बेंचमार्क प्रत्येक विकल्प के औसत समय को मापता है। अधिक जानकारी के लिए GitHub पर मेरा कार्यान्वयन देखें ।

पूर्णता के लिए: इस उत्तर और मेरे बेंचमार्क का पिछला संस्करण है

परिणाम

| ऑपरेशन | ऑपरेशन में नैनोसेकंड में रनटाइम | Instof के सापेक्ष |
| ------------ | ------------------------------------ - | ------------------------ |
| INSTANCEOF | 39,598 ,5 0,022 ns / op | 100,00% |
| GETCLASS | 39,687 ,6 0,021 ns / op | 100,22% |
| TYPE | 46,295 ,0 0,026 ns / op | 116,91% |
| OO | 48,078 ± 0,026 ns / op | 121,42% |

tl; डॉ

जावा 1.8 instanceofमें सबसे तेज दृष्टिकोण है, हालांकि getClass()बहुत करीब है।


58
+0.(9)विज्ञान के लिए!

16
+ मेरे से अन्य 0.1: डी
टोबियास रीच

14
@TobiasReich तो हमें मिल गया +1.0(9)। :)
पावेल

9
मुझे नहीं लगता कि यह कोई भी उपाय सार्थक है। System.currentTimeMillis()एक ऑपरेशन पर उपयोग करने वाले कोड उपाय एक एकल विधि कॉल की तुलना में बहुत अधिक नहीं है, जो कम सटीकता के लिए बहुत कुछ देना चाहिए। इसके बजाय JMH जैसे बेंचमार्क फ्रेमवर्क का उपयोग करें !
Lii

6
या सिर्फ कॉल के बजाय पूरे बिलियन कॉल की टाइमिंग करें।
लीजेंडलेंथ्रान

74

मैंने सिर्फ यह देखने के लिए एक सरल परीक्षण किया कि कैसे एक साधारण s.equals () कॉल की तुलना केवल एक अक्षर के साथ की जाती है।

एक 10.000.000 लूप में उदाहरण के लिए मुझे 63-96ms दिया, और स्ट्रिंग बराबर मुझे 106-230ms दिया

मैंने जावा jvm 6 का इस्तेमाल किया।

इसलिए मेरे सरल परीक्षण में एक चरित्र स्ट्रिंग तुलना के बजाय एक उदाहरण करना अधिक तेज़ है।

स्ट्रिंग के बजाए इंटेगर के असमान () का उपयोग करने से मुझे वही परिणाम मिला, जब मैंने == का उपयोग किया था, मैं उदाहरण के लिए 20ms (10.000.000 लूप में) से तेज था


4
क्या आपके लिए यहां कोड पोस्ट करना संभव होगा? वह तो जबर्दस्त होगा!
अल्केमिस्ट

7
उदाहरण के लिए कैसे बहुरूपता समारोह प्रेषण की तुलना की गई?
क्रिस

21
आप एक String.equals () के साथ Instof की तुलना क्यों करते हैं? आप प्रकार आप object.getClass () करने के लिए करने के लिए है जाँच करना चाहते हैं बराबर (SomeType.class)।
marsbear

4
@marsbear equals()इसे नहीं काटेगा , क्योंकि उपवर्ग; आप की जरूरत isAssignableFrom()
डेविड मोल्स

1
@marsbear राइट, लेकिन ओपी क्या पूछ रहा था इसका कोई बेहतर परीक्षण नहीं है।
डेविड मोल्स

20

जो आइटम प्रदर्शन प्रभाव का निर्धारण करेंगे, वे हैं:

  1. उन संभावित वर्गों की संख्या, जिनके लिए इंस्टॉफ़ ऑपरेटर सही लौटा सकता है
  2. आपके डेटा का वितरण - पहले या दूसरे प्रयास में हल किए गए अधिकांश इंस्टाफॉरेक्ट ऑपरेशन हैं? आप पहले सच्चा संचालन वापस करने के लिए अपनी सबसे अधिक संभावना रखना चाहते हैं।
  3. परिनियोजन वातावरण। सन सोलारिस वीएम पर चलना सूर्य के विंडोज जेवीएम की तुलना में काफी अलग है। सोलारिस डिफ़ॉल्ट रूप से 'सर्वर' मोड में चलेगा, जबकि विंडोज क्लाइंट मोड में चलेगा। सोलारिस पर जेआईटी अनुकूलन, सभी विधि का उपयोग समान कर देगा।

मैंने प्रेषण के चार अलग-अलग तरीकों के लिए एक माइक्रोबेनमार्क बनाया । सोलारिस के परिणाम निम्नानुसार हैं, जिनकी संख्या कम है:

InstanceOf 3156
class== 2925 
OO 3083 
Id 3067 

18

आपके अंतिम प्रश्न का उत्तर देना: जब तक कि कोई प्रोफाइलर आपको यह नहीं बताता है, कि आप एक उदाहरण में हास्यास्पद मात्रा में समय बिताते हैं: हाँ, आप निपटा रहे हैं।

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

अत्यधिक अनुकूलन करने वाले समय में, बाधाओं के बारे में आपके अनुमान पूरी तरह से गलत होने की संभावना होगी।

और इस उत्तर की सच्ची भावना (जिसे मैं पूरी ईमानदारी से मानता हूं): मुझे बिल्कुल नहीं पता है कि एक बार जीआईटी-कंपाइलर को इसे ऑप्टिमाइज़ करने का मौका मिलने के बाद कैसे संबंध और == संबंधित हैं।

मैं भूल गया: पहले रन को कभी न मापें।


1
लेकिन मूल पोस्टर में उल्लेख किया गया प्रदर्शन इस एप्लिकेशन के लिए महत्वपूर्ण था, इसलिए उस स्थिति में शुरुआती अनुकूलन करना अनुचित नहीं है। दूसरे शब्दों में आप GWBasic में एक 3D गेम नहीं लिखेंगे और फिर अंत में कहेंगे, ठीक है, इसे अनुकूलित करना शुरू करते हैं, पहला चरण इसे c ++ में पोर्ट करना है।
लीजेंडल्रिक्स

यदि उचित पुस्तकालय उपलब्ध हैं, तो GWBasic 3D गेम्स के लिए एक शानदार शुरुआत हो सकती है। लेकिन यह एक तरफ (जैसा कि यह एक कृत्रिम तर्क है): ओपी अनुकूलन के रूप में एक पूर्ण पुनर्लेखन के लिए नहीं कह रहा है। यह एक एकल निर्माण के बारे में है जहां हम यह भी नहीं जानते हैं कि क्या प्रभाव महत्वपूर्ण है (भले ही कंपाइलर के वर्तमान संस्करण में भी ऐसा ही बेहतर प्रदर्शन करने का तरीका हो )। मैं मजबूती से c2.com/cgi/wiki?ProfileBeforeOptOptimizing और मेरे जवाब के पीछे खड़ा हूं। प्रारंभिक अनुकूलन सभी बुराई की जड़ है! यह रखरखाव को कठिन बनाता है - और रखरखाव वह पहलू है जो अनुकूलन के लायक है
Olaf Kock

15

मुझे एक ही सवाल मिला है, लेकिन क्योंकि मुझे खदान के समान उपयोग के मामले में 'प्रदर्शन मेट्रिक्स' नहीं मिला है, मैंने कुछ और नमूना कोड किए हैं। मेरे हार्डवेयर और जावा 6 और 7 पर, 10mln पुनरावृत्तियों पर Instof और स्विच के बीच का अंतर है

for 10 child classes - instanceof: 1200ms vs switch: 470ms
for 5 child classes  - instanceof:  375ms vs switch: 204ms

तो, उदाहरण के लिए, वास्तव में धीमी है, खासकर अगर-और-अगर बयानों की भारी संख्या पर, हालांकि अंतर वास्तविक आवेदन के भीतर नगण्य होगा।

import java.util.Date;

public class InstanceOfVsEnum {

    public static int c1, c2, c3, c4, c5, c6, c7, c8, c9, cA;

    public static class Handler {
        public enum Type { Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9, TypeA }
        protected Handler(Type type) { this.type = type; }
        public final Type type;

        public static void addHandlerInstanceOf(Handler h) {
            if( h instanceof H1) { c1++; }
            else if( h instanceof H2) { c2++; }
            else if( h instanceof H3) { c3++; }
            else if( h instanceof H4) { c4++; }
            else if( h instanceof H5) { c5++; }
            else if( h instanceof H6) { c6++; }
            else if( h instanceof H7) { c7++; }
            else if( h instanceof H8) { c8++; }
            else if( h instanceof H9) { c9++; }
            else if( h instanceof HA) { cA++; }
        }

        public static void addHandlerSwitch(Handler h) {
            switch( h.type ) {
                case Type1: c1++; break;
                case Type2: c2++; break;
                case Type3: c3++; break;
                case Type4: c4++; break;
                case Type5: c5++; break;
                case Type6: c6++; break;
                case Type7: c7++; break;
                case Type8: c8++; break;
                case Type9: c9++; break;
                case TypeA: cA++; break;
            }
        }
    }

    public static class H1 extends Handler { public H1() { super(Type.Type1); } }
    public static class H2 extends Handler { public H2() { super(Type.Type2); } }
    public static class H3 extends Handler { public H3() { super(Type.Type3); } }
    public static class H4 extends Handler { public H4() { super(Type.Type4); } }
    public static class H5 extends Handler { public H5() { super(Type.Type5); } }
    public static class H6 extends Handler { public H6() { super(Type.Type6); } }
    public static class H7 extends Handler { public H7() { super(Type.Type7); } }
    public static class H8 extends Handler { public H8() { super(Type.Type8); } }
    public static class H9 extends Handler { public H9() { super(Type.Type9); } }
    public static class HA extends Handler { public HA() { super(Type.TypeA); } }

    final static int cCycles = 10000000;

    public static void main(String[] args) {
        H1 h1 = new H1();
        H2 h2 = new H2();
        H3 h3 = new H3();
        H4 h4 = new H4();
        H5 h5 = new H5();
        H6 h6 = new H6();
        H7 h7 = new H7();
        H8 h8 = new H8();
        H9 h9 = new H9();
        HA hA = new HA();

        Date dtStart = new Date();
        for( int i = 0; i < cCycles; i++ ) {
            Handler.addHandlerInstanceOf(h1);
            Handler.addHandlerInstanceOf(h2);
            Handler.addHandlerInstanceOf(h3);
            Handler.addHandlerInstanceOf(h4);
            Handler.addHandlerInstanceOf(h5);
            Handler.addHandlerInstanceOf(h6);
            Handler.addHandlerInstanceOf(h7);
            Handler.addHandlerInstanceOf(h8);
            Handler.addHandlerInstanceOf(h9);
            Handler.addHandlerInstanceOf(hA);
        }
        System.out.println("Instance of - " + (new Date().getTime() - dtStart.getTime()));

        dtStart = new Date();
        for( int i = 0; i < cCycles; i++ ) {
            Handler.addHandlerSwitch(h1);
            Handler.addHandlerSwitch(h2);
            Handler.addHandlerSwitch(h3);
            Handler.addHandlerSwitch(h4);
            Handler.addHandlerSwitch(h5);
            Handler.addHandlerSwitch(h6);
            Handler.addHandlerSwitch(h7);
            Handler.addHandlerSwitch(h8);
            Handler.addHandlerSwitch(h9);
            Handler.addHandlerSwitch(hA);
        }
        System.out.println("Switch of - " + (new Date().getTime() - dtStart.getTime()));
    }
}

जो परिणाम java 6 था और जो java 7 था? क्या आपने जावा 8 के तहत इसका पुनरीक्षण किया है? यहाँ पर अधिक महत्वपूर्ण बात यह है कि यदि आप केस के स्टेटमेंट को इन्टास पर अनिवार्य करते हैं तो एक लंबाई की तुलना कर रहे हैं। मुझे लगता है कि हम एक इंट स्विच को तेजी से हल्का करने की उम्मीद करेंगे।
एज़रोथ 2

1
मुझे ठीक से याद नहीं है कि 5 साल पहले क्या हो रहा था - मुझे लगता है कि जावा 6 और जावा 7 दोनों का परिणाम समान था, इसीलिए केवल एक परिणाम प्रदान किया गया है (बशर्ते 2 लाइनें वर्ग पदानुक्रम की अलग-अलग गहराई के लिए हों ...) और नहीं , मैंने जावा के साथ तुलना करने की कोशिश नहीं की। 8. परीक्षण का पूरा कोड प्रदान किया गया है - आप इसे कॉपी / पेस्ट कर सकते हैं और उन वातावरण में जांच कर सकते हैं जिनकी आपको आवश्यकता है (ध्यान दें - आजकल मैं इसके लिए जेएमएच परीक्षण का उपयोग करूंगा)।
एक्स्ट्रा कोडर

9

instanceof वास्तव में तेज है, केवल कुछ सीपीयू निर्देश ले रहा है।

जाहिरा तौर पर, यदि किसी वर्ग Xमें कोई उपवर्ग लोड नहीं है (JVM जानता है), तो instanceofइसे इस प्रकार अनुकूलित किया जा सकता है:

     x instanceof X    
==>  x.getClass()==X.class  
==>  x.classID == constant_X_ID

मुख्य लागत सिर्फ एक पढ़ा है!

यदि Xउपवर्ग लोड किए गए हैं, तो कुछ और रीड की आवश्यकता होती है; वे संभवतः सह-स्थित हैं इसलिए अतिरिक्त लागत बहुत कम है।

सबके लिए अच्छी खबर है!


2
अनुकूलित या अनुकूलित किया जा सकता है ? स्रोत?

@vaxquis इसके जेवीएम को विशिष्ट मान सकता है
RecursiveExceptionException

@itzJanuary विलाप आप मेरे सवाल यहाँ की बात याद किया: हर कोई जानता है कि संकलक कर सकते हैं अनुकूलन foo- लेकिन है fooवास्तव में वर्तमान में Oracle की javac / VM द्वारा अनुकूलित - या यह सिर्फ है कि यह भविष्य में उस करूँगा संभव है? इसके अलावा, मैंने उत्तर देने वाले से पूछा कि क्या उसके पास कोई बैकिंग स्रोत है (जैसा कि यह डॉक्स, सोर्स कोड, देव ब्लॉग है) यह दस्तावेज करता है कि यह वास्तव में अनुकूलित किया जा सकता है या अनुकूलित है ? इसके बिना, यह उत्तर सिर्फ कुछ यादृच्छिक मांसपेशियों के बारे में है जो संकलक संभवतः कर सकते हैं।

@vaxview आपने हॉटस्पॉट वीएम का कभी उल्लेख नहीं किया है लेकिन उस स्थिति में मुझे नहीं पता कि यह "अनुकूलित" है या नहीं।
RecursiveExceptionException

1
हाल ही में पढ़ा कि JIT (JVM 8) प्रत्यक्ष कॉल द्वारा 1 या 2 प्रकारों के लिए एक कॉल साइट को ऑप्टिमाइज़ करेगा, लेकिन दो वास्तविक प्रकारों से अधिक का सामना होने पर व्यवहार्य होने का संकेत देता है। इसलिए रनटाइम पर कॉल साइट से गुजरने वाले केवल दो ठोस प्रकार एक प्रदर्शन लाभ का प्रतिनिधित्व करते हैं।
सिमोन .वाट्स

5

Instanceof बहुत तेज है। यह एक बाइटकोड से उबलता है जो वर्ग संदर्भ तुलना के लिए उपयोग किया जाता है। लूप में कुछ मिलियन इंस्टाफॉर्स आज़माएं और अपने लिए देखें।


5

Instof शायद सबसे वास्तविक दुनिया कार्यान्वयन में एक साधारण बराबरी की तुलना में अधिक महंगा होने जा रहा है (यानी, जहां instof वास्तव में जरूरत है, और आप इसे हर सामान्य पाठ्यपुस्तक के साथ-साथ एक सामान्य विधि को ओवरराइड करके भी हल नहीं कर सकते हैं) सुझाव के ऊपर डेमियन)।

ऐसा क्यों है? क्योंकि जो संभवत: होने वाला है वह यह है कि आपके पास कई इंटरफेस हैं, जो कुछ कार्यक्षमता प्रदान करते हैं (मान लीजिए, x, y और z) को इंटरफेस करते हैं, और कुछ वस्तुओं को हेरफेर करने के लिए (या नहीं) उन इंटरफेस में से एक को लागू कर सकते हैं ... लेकिन प्रत्यक्ष नहीं। उदाहरण के लिए, कहो, मेरे पास है:

w एक्स का विस्तार करता है

एक औजार डब्ल्यू

B, A का विस्तार करता है

C, B को लागू करता है, y को लागू करता है

D, C को लागू करता है, Z को लागू करता है

मान लीजिए कि मैं D, वस्तु d के उदाहरण को संसाधित कर रहा हूं। कम्प्यूटिंग (उदाहरण के लिए x) को d.getClass () लेने की आवश्यकता होती है, इंटरफेस के माध्यम से लूप यह जानने के लिए लागू होता है कि क्या एक == से x है, और यदि ऐसा नहीं है तो फिर से अपने सभी पूर्वजों के लिए ... हमारे मामले में यदि आप उस पेड़ की चौड़ाई की पहली खोज करते हैं, तो कम से कम 8 तुलनाएँ प्राप्त करते हैं, जो कि y और z को किसी भी चीज़ का विस्तार नहीं करते ...

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

अगर यह एक मुद्दा बन जाता है, तो मैं इसके बजाय हैंडलर मैप का उपयोग करने का सुझाव दूंगा, ऑब्जेक्ट के कंक्रीट वर्ग को एक क्लोजर से जोड़ता है जो हैंडलिंग करता है। यह प्रत्यक्ष मानचित्रण के पक्ष में ट्री ट्रैवर्सल चरण को हटा देता है। हालाँकि, सावधान रहें कि यदि आपने C.class के लिए कोई हैंडलर सेट किया है, तो ऊपर दी गई मेरी वस्तु पहचानी नहीं जाएगी।

यहाँ मेरे 2 सेंट हैं, मुझे आशा है कि वे मदद करेंगे ...


5

Instof बहुत कुशल है, इसलिए आपके प्रदर्शन को नुकसान होने की संभावना नहीं है। हालांकि, बहुत सारे उदाहरणों का उपयोग करना एक डिज़ाइन समस्या का सुझाव देता है।

यदि आप xClass == String.class का उपयोग कर सकते हैं, तो यह तेज़ है। नोट: आपको अंतिम कक्षाओं के लिए इंस्टोफ़ की आवश्यकता नहीं है।


1
Btw आप "अंतिम वर्गों के लिए Instof की जरूरत नहीं है" से क्या मतलब है?
पेसर

एक अंतिम वर्ग में उप कक्षाएं नहीं हो सकती हैं। इस मामले x.getClass() == Class.classमें भी यही हैx instanceof Class
पीटर लॉरी

कूल, यह मानते हुए कि x शून्य नहीं है, जो आप पसंद करेंगे?
पचेरियर

अच्छी बात। यह इस पर निर्भर करेगा कि क्या मैं उम्मीद xहोने के लिए nullमुझे लगता है। (या जो भी स्पष्ट हो)
पीटर लॉरी

हम्म मुझे बस एहसास हुआ कि हम java.lang.class.isAssignableFrom का भी उपयोग कर सकते हैं, क्या आप जानते हैं कि अगर इनफ्लो कीवर्ड आंतरिक रूप से इन जैसे कार्यों का उपयोग करता है?
पचेरियर

4

आम तौर पर कारण है कि "इंस्टाफ़ॉफ़" ऑपरेटर को इस तरह के मामले में (जहाँ इस बेस क्लास के उपवर्गों के लिए जाँच की जा रही है) पर फेंक दिया जाता है क्योंकि आप जो कर रहे हैं वह एक विधि में चल रहा है और इसे उपयुक्त के लिए ओवरराइड कर रहा है उपवर्गों। उदाहरण के लिए, यदि आपके पास:

if (o instanceof Class1)
   doThis();
else if (o instanceof Class2)
   doThat();
//...

आप इसे बदल सकते हैं

o.doEverything();

और उसके बाद Class1 कॉल "doThis ()", और Class2 कॉल "doThat ()", और इसी तरह "doEverything ()" का कार्यान्वयन किया है।


11
लेकिन कभी-कभी आप नहीं कर सकते। यदि आप एक ऐसे इंटरफ़ेस को लागू कर रहे हैं जो आपके पास एक ऑब्जेक्ट में है, और आपको यह बताने की आवश्यकता है कि यह किस प्रकार का है, तो Instof वास्तव में एकमात्र विकल्प है। आप कास्टिंग की कोशिश कर सकते हैं, लेकिन आम तौर पर क्लीनर साफ है।
हर्म्स

4

'इंस्टाफॉफ़' वास्तव में एक ऑपरेटर है, जैसे + या - और मेरा मानना ​​है कि इसका अपना जेवीएम बाइटकोड निर्देश है। यह काफी तेज होना चाहिए।

मुझे यह नहीं चाहिए कि यदि आपके पास एक स्विच है जहां आप परीक्षण कर रहे हैं यदि कोई वस्तु कुछ उप-वर्ग का उदाहरण है, तो आपके डिजाइन को फिर से काम करने की आवश्यकता हो सकती है। उपवर्ग विशिष्ट व्यवहार को उपवर्ग में नीचे धकेलने पर विचार करें।


4

डेमियन और पॉल एक अच्छे बिंदु का उल्लेख करते हैं; हालाँकि , कोड को लागू करना वास्तव में इस बात पर निर्भर करता है कि आप डेटा का उपयोग कैसे करना चाहते हैं ...

मैं छोटे डेटा ऑब्जेक्ट्स का बहुत बड़ा प्रशंसक हूं जिनका उपयोग कई तरीकों से किया जा सकता है। यदि आप ओवरराइड (बहुरूपी) दृष्टिकोण का पालन करते हैं, तो आपकी वस्तुओं का केवल "एक ही रास्ता" इस्तेमाल किया जा सकता है।

यह वह जगह है जहाँ पैटर्न आते हैं ...

आप प्रत्येक ऑब्जेक्ट को "कॉलिंग यू" कहने के लिए डबल-प्रेषण (जैसा कि विज़िटर पैटर्न में) का उपयोग कर सकते हैं - खुद को पास करने के लिए - यह ऑब्जेक्ट के प्रकार को हल करेगा। हालाँकि (फिर से) आपको एक वर्ग की आवश्यकता होगी जो सभी संभव उपप्रकारों के साथ "सामान" कर सके।

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

उम्मीद है कि यह कुछ अन्य विचारों को प्रेरित करेगा ...

package com.javadude.sample;

import java.util.HashMap;
import java.util.Map;

public class StrategyExample {
    static class SomeCommonSuperType {}
    static class SubType1 extends SomeCommonSuperType {}
    static class SubType2 extends SomeCommonSuperType {}
    static class SubType3 extends SomeCommonSuperType {}

    static interface Handler<T extends SomeCommonSuperType> {
        Object handle(T object);
    }

    static class HandlerMap {
        private Map<Class<? extends SomeCommonSuperType>, Handler<? extends SomeCommonSuperType>> handlers_ =
            new HashMap<Class<? extends SomeCommonSuperType>, Handler<? extends SomeCommonSuperType>>();
        public <T extends SomeCommonSuperType> void add(Class<T> c, Handler<T> handler) {
            handlers_.put(c, handler);
        }
        @SuppressWarnings("unchecked")
        public <T extends SomeCommonSuperType> Object handle(T o) {
            return ((Handler<T>) handlers_.get(o.getClass())).handle(o);
        }
    }

    public static void main(String[] args) {
        HandlerMap handlerMap = new HandlerMap();

        handlerMap.add(SubType1.class, new Handler<SubType1>() {
            @Override public Object handle(SubType1 object) {
                System.out.println("Handling SubType1");
                return null;
            } });
        handlerMap.add(SubType2.class, new Handler<SubType2>() {
            @Override public Object handle(SubType2 object) {
                System.out.println("Handling SubType2");
                return null;
            } });
        handlerMap.add(SubType3.class, new Handler<SubType3>() {
            @Override public Object handle(SubType3 object) {
                System.out.println("Handling SubType3");
                return null;
            } });

        SubType1 subType1 = new SubType1();
        handlerMap.handle(subType1);
        SubType2 subType2 = new SubType2();
        handlerMap.handle(subType2);
        SubType3 subType3 = new SubType3();
        handlerMap.handle(subType3);
    }
}

4

मैं jhh-java-benchmark-archetype: 2.21 पर आधारित प्रदर्शन परीक्षण लिखता हूं। JDK Openjdk है और संस्करण 1.8.0_212 है। टेस्ट मशीन मैक प्रो है। परीक्षा परिणाम है:

Benchmark                Mode  Cnt    Score   Error   Units
MyBenchmark.getClasses  thrpt   30  510.818 ± 4.190  ops/us
MyBenchmark.instanceOf  thrpt   30  503.826 ± 5.546  ops/us

परिणाम से पता चलता है कि: getClass उदाहरण से बेहतर है, जो अन्य परीक्षण के साथ विपरीत है। हालाँकि, मुझे नहीं पता कि क्यों।

परीक्षण कोड नीचे है:

public class MyBenchmark {

public static final Object a = new LinkedHashMap<String, String>();

@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public boolean instanceOf() {
    return a instanceof Map;
}

@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public boolean getClasses() {
    return a.getClass() == HashMap.class;
}

public static void main(String[] args) throws RunnerException {
    Options opt =
        new OptionsBuilder().include(MyBenchmark.class.getSimpleName()).warmupIterations(20).measurementIterations(30).forks(1).build();
    new Runner(opt).run();
}
}

अगर मैं अटकलें लगाता था, तो क्या उदाहरण देता है, यकीनन ज्यादा जटिल है। एक getClass () == चेक एक सटीक 1: 1 चेक करेगा, जहां इंस्टोफ़ एक पदानुक्रम की जाँच करता है अर्थात myHashSet इंस्टोफ़ कलेक्शन पास होगा, लेकिन myHashSet.getClass () == Collection.classass नहीं होगा। अनिवार्य रूप से, वे समान संचालन नहीं हैं, इसलिए मुझे बहुत आश्चर्य नहीं है कि प्रदर्शन अलग भी है।
AMTerp

3

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

if (o instanceof java.lang.String)

निम्न C कोड जितना तेज़ हो सकता है

if (objectStruct->iAmInstanceOf == &java_lang_String_class)

एक जेआईटी संकलक की जगह है और एक अच्छा काम करता है।

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

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


1
क्या यह पता लगाना नहीं है कि क्या java.lang.String से ओ विरासत में मिला है?
डब्ल्यूडब्ल्यू।

1
इसलिए मैंने कहा कि यह "हो सकता है" जितना तेज़ हो। वास्तव में यह एक पाश प्रदर्शन करता है, पहले प्रश्न में वर्ग के खिलाफ iAmInstanceOf की जाँच करता है, फिर यह o के वंशानुक्रम वृक्ष के ऊपर जाता है और प्रत्येक सुपर-वर्ग o के लिए इस जाँच को दोहराता है (इसलिए इसे इस पाश को एक-दो बार चलाना पड़ सकता है। एक मैच के लिए)
मेकी

3

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


2

InstanceOf खराब ऑब्जेक्ट ओरिएंटेड डिज़ाइन की चेतावनी है।

वर्तमान जेवीएम का मतलब है कि उदाहरण ओएफएफ अपने आप में एक प्रदर्शन चिंता का विषय नहीं है। यदि आप अपने आप को इसका उपयोग करते हुए पा रहे हैं, विशेष रूप से कोर कार्यक्षमता के लिए, तो यह संभवतः डिजाइन को देखने का समय है। प्रदर्शन (और सादगी / रख-रखाव) एक बेहतर डिजाइन करने के लिए पुनर्रचना के लाभ बहुत वास्तविक पर खर्च किसी भी वास्तविक प्रोसेसर चक्र पल्ला झुकना होगा instanceof कॉल।

एक बहुत छोटा सा सरल प्रोग्रामिंग उदाहरण देने के लिए।

if (SomeObject instanceOf Integer) {
  [do something]
}
if (SomeObject instanceOf Double) {
  [do something different]
}

क्या कोई गरीब आर्किटेक्चर एक बेहतर विकल्प होता है कि कोई ओबजेक्ट दो चाइल्ड क्लास का पैरेंट क्लास हो, जहां प्रत्येक चाइल्ड क्लास एक मेथड (डूमस्ट्रीम) को ओवरराइड करता है, इसलिए कोड इस तरह दिखेगा:

Someobject.doSomething();

61
मुझे यह बात पता है। जो मैंने पूछा था वह नहीं था।
जोश

इस बात पर ध्यान देना कि यह वोट देना है या नहीं क्योंकि यह एक अच्छा बिंदु है, लेकिन पूछे गए सवाल का जवाब नहीं देता ...
jklp

7
मुझे लगता है कि कोड का उदाहरण वास्तव में बहुत बुरा है: आप वर्ग डबल का विस्तार नहीं कर सकते हैं, और यह भी कि आप किसी अन्य वर्ग से डबल प्राप्त नहीं कर सकते हैं। यदि आपने उदाहरण के लिए अन्य वर्गों का उपयोग किया है, तो यह ठीक होगा।
लीना शिमेलमेल

6
इसके अलावा अगर SomeObject के चाइल्ड क्लासेस वैल्यू ऑब्जेक्ट हैं, तो आप उनमें तर्क नहीं रखना चाहते हैं। ईजी पाई और रोस्ट पुटीन ओवेन () और पुटमाउथ () लॉजिक के लिए सही जगह नहीं हो सकती है।
स्के।

सेल्फ कुकिंग पाई और
भुट्टा

2

आधुनिक जावा संस्करण में सरल विधि कॉल के रूप में इंस्टाफॉपर ऑपरेटर तेजी से होता है। इसका मतलब है की:

if(a instanceof AnyObject){
}

के रूप में तेजी से है:

if(a.getType() == XYZ){
}

एक और बात यह है कि अगर आपको कई उदाहरणों को समझने की जरूरत है। फिर एक स्विच जो केवल गेटटाइप को कॉल करता है () तेज है।


1

यदि गति आपका एकमात्र उद्देश्य है, तो उप-वर्गों की पहचान करने के लिए इंट कॉन्स्टेंट्स का उपयोग करना समय की एक मिलीसेकंड दाढ़ी बनाने के लिए लगता है

static final int ID_A = 0;
static final int ID_B = 1;
abstract class Base {
  final int id;
  Base(int i) { id = i; }
}
class A extends Base {
 A() { super(ID_A); }
}
class B extends Base {
 B() { super(ID_B); }
}
...
Base obj = ...
switch(obj.id) {
case  ID_A: .... break;
case  ID_B: .... break;
}

भयानक OO डिज़ाइन, लेकिन यदि आपका प्रदर्शन विश्लेषण यह इंगित करता है कि आप कहाँ अड़चन है तो हो सकता है। मेरे कोड में प्रेषण कोड कुल निष्पादन समय का 10% लेता है और शायद यह 1% कुल गति में सुधार में योगदान देता है।


0

आपको मापना चाहिए / प्रोफाइल अगर यह वास्तव में आपके प्रोजेक्ट में एक प्रदर्शन मुद्दा है। यदि यह है तो मैं एक नया स्वरूप सुझा सकता हूँ - यदि संभव हो तो। मुझे पूरा यकीन है कि आप प्लेटफ़ॉर्म के मूल कार्यान्वयन (C में लिखा गया) को हरा नहीं सकते। आपको इस मामले में कई विरासत पर भी विचार करना चाहिए।

आपको समस्या के बारे में अधिक बताना चाहिए, हो सकता है कि आप एक सहयोगी स्टोर का उपयोग कर सकते हैं, उदाहरण के लिए मैप <क्लास, ऑब्जेक्ट> यदि आप केवल ठोस प्रकारों में रुचि रखते हैं।


0

पीटर लॉरी के नोट के संबंध में कि आपको अंतिम कक्षाओं के लिए इंस्टोफ़ की आवश्यकता नहीं है और बस एक संदर्भ समानता का उपयोग कर सकते हैं, सावधान रहें! भले ही अंतिम कक्षाओं का विस्तार नहीं किया जा सकता है, लेकिन उन्हें उसी क्लास लोडर द्वारा लोड किए जाने की गारंटी नहीं है। केवल x.getClass () == SomeFinal.class या इसके ilk का उपयोग करें यदि आप पूरी तरह से सकारात्मक हैं कि कोड के उस भाग के लिए खेलने में केवल एक क्लास लोडर है।


4
यदि एक वर्ग को अलग-अलग क्लास लोडर द्वारा लोड किया जाता है, तो मुझे नहीं लगता कि इंस्टोफ या तो मैच करेगा।
पीटर लॉरी

0

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

public abstract class Base
{
  protected enum TYPE
  {
    DERIVED_A, DERIVED_B
  }

  public abstract TYPE getType();

  class DerivedA extends Base
  {
    @Override
    public TYPE getType()
    {
      return TYPE.DERIVED_A;
    }
  }

  class DerivedB extends Base
  {
    @Override
    public TYPE getType()
    {
      return TYPE.DERIVED_B;
    }
  }
}

0

मुझे लगा कि इस पृष्ठ पर आम सहमति के लिए एक काउंटर-उदाहरण प्रस्तुत करने के लायक हो सकता है कि "Instof" के बारे में चिंता करने के लिए पर्याप्त महंगा नहीं है। मैंने पाया कि मेरे पास एक आंतरिक लूप में कुछ कोड था (अनुकूलन में कुछ ऐतिहासिक प्रयास में)

if (!(seq instanceof SingleItem)) {
  seq = seq.head();
}

जहाँ कॉलिंग हेड () सिंगल इटेम पर मान अपरिवर्तित देता है। द्वारा कोड की जगह

seq = seq.head();

मुझे 269ms से 169ms की गति प्रदान करता है, इस तथ्य के बावजूद कि लूप में कुछ भारी चीजें हो रही हैं, जैसे कि स्ट्रिंग-टू-डबल रूपांतरण। यह निश्चित रूप से संभव है कि गति-प्रवाह सशर्त शाखा को समाप्त करने के कारण अधिक है, उदाहरण के लिए संचालक को समाप्त करने के बजाय; लेकिन मैंने इसे ध्यान देने योग्य समझा।


यह ifस्वयं के कारण हो सकता है। यदि trues और falses का वितरण समीप है, तो सट्टा निष्पादन बेकार हो जाता है, जो महत्वपूर्ण अंतराल की ओर जाता है।
दिमित्रो

-4

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


7
यह आधुनिक जावा कचरा संग्रह एल्गोरिदम की तुलना में बहुत कम सच है जितना कि यह कभी हुआ करता था। यहां तक ​​कि सबसे सरल एल्गोरिदम किसी भी अधिक परवाह नहीं करते हैं कि आप उपयोग करने के बाद कितनी स्मृति को छोड़ देते हैं - वे केवल यह ध्यान रखते हैं कि युवा-पीढ़ी के संग्रह में कितना बनाए रखा गया है।
बिल माइकेल

3
महान, सिवाय इसके कि मैं सबसे हालिया जेवीएम पर हूं और मेरा कंप्यूटर अभी भी क्रॉल करता है जब जीसी चलता है। दोहरे कोर पर, 3 जीबी रैम सर्वर। यदि प्रदर्शन वास्तव में मायने रखता है तो जावा उपयोग करने के लिए एक भाषा नहीं है।
०0:२० पर ०0

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

6
@tloach मुझे खराब ऐप डिज़ाइन की तरह लगता है। आप "प्रदर्शन" के बारे में बात करते हैं जैसे कि यह एक आयामी था। मैंने बहुत से जावा एप्स के साथ (और) काम किया है, जो उदाहरण के लिए, बहुत इंटरैक्टिव डेटा विश्लेषण और बहुत बड़े डेटा सेटों के प्रदर्शन में व्यंग्यात्मक इंटरैक्टिव सांख्यिकीय विश्लेषण प्रदान करने या बहुत बड़े लेनदेन संस्करणों को संसाधित करने में बहुत तेज़ी से काम करते हैं। "प्रदर्शन" केवल एक चीज नहीं है, और यह तथ्य कि कोई व्यक्ति एक ऐसा एप्लिकेशन लिख सकता है जो स्मृति को बुरी तरह से प्रबंधित करता है और GC को अपने तरीके से प्राप्त करने देता है इसका मतलब यह नहीं है कि "प्रदर्शन" की आवश्यकता कुछ और में लिखी जानी चाहिए।
डेविड मोल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.