जावा के लिए C ++ की तुलना में तेज़ होना कभी क्यों संभव होगा?


79

कभी-कभी जावा बेंचमार्क में C ++ से बेहतर प्रदर्शन करता है। बेशक, कभी-कभी C ++ आउटपरफॉर्म करता है।

निम्नलिखित लिंक देखें:

लेकिन यह कैसे भी संभव है? यह मेरे दिमाग को चकित करता है कि बाईटेकोड की व्याख्या कभी भी संकलित भाषा से तेज हो सकती है।

क्या कोई समझा सकता है? धन्यवाद!


2
आप
jw

2
देखिए जावा में धीमा होने की प्रतिष्ठा क्यों थी? इस विषय पर बहुत जानकारी के लिए।
Péter Török

11
यह जावा वीएम का उत्पादन करने के लिए कानून (धारा 10.101.04.2c) के खिलाफ है जो C ++ के साथ उत्पादित निष्पादन योग्य बाइनरी की तुलना में तेजी से प्रदर्शन करता है।
मतीन उल्हाक

1
@ मंटू पृथ्वी पर आपका क्या मतलब है? धारा 10.101.04.2 का क्या?
हाईलैंड मार्क

3
@HighlandMark आप मंडली के सदस्य नहीं हैं। आपको पता नहीं है कि सर्कल के अंदर क्या जाता है। सर्कल निरपेक्ष है - सर्कल के नियम प्रकृति के सुपरसाइड करते हैं। आप न तो चक्र को टाल सकते हैं और न ही प्रश्न कर सकते हैं। मैं चक्र हूं और सर्कल मैं हूं।
मतीन उल्हाक

जवाबों:


108

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

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

  init0 = (int*)calloc(max_x,sizeof(int));
  init1 = (int*)calloc(max_x,sizeof(int));
  init2 = (int*)calloc(max_x,sizeof(int));
  for (x=0; x<max_x; x++) {
    init2[x] = 0;
    init1[x] = 0;
    init0[x] = 0;
  }

चूंकि callocस्मृति पहले से ही forशून्य है , लूप का उपयोग करके इसे फिर से शून्य करने के लिए स्पष्ट रूप से बेकार है। मेमोरी को अन्य डेटा के साथ (और शून्य होने पर कोई निर्भरता नहीं) भरने के बाद इसका अनुसरण किया गया था, इसलिए सभी शून्यिंग वैसे भी पूरी तरह से अनावश्यक थीं। ऊपर दिए गए कोड को सरल के साथ बदलना malloc(जैसे किसी भी समझदार व्यक्ति के साथ शुरू करने के लिए इस्तेमाल किया होगा) ने जावा संस्करण को हरा देने के लिए C ++ संस्करण की गति में काफी सुधार किया (यदि स्मृति कार्य करती है तो काफी व्यापक अंतर से)।

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

class Toggle {
public:
    Toggle(bool start_state) : state(start_state) { }
    virtual ~Toggle() {  }
    bool value() {
        return(state);
    }
    virtual Toggle& activate() {
        state = !state;
        return(*this);
    }
    bool state;
};

महत्वपूर्ण हिस्सा निकला state = !state;। विचार करें कि जब हम राज्य को एक के intबजाय कोड को बदलने के लिए कोड बदलते हैं तो क्या होता है bool:

class Toggle {
    enum names{ bfalse = -1, btrue = 1};
    const static names values[2];
    int state;

public:
    Toggle(bool start_state) : state(values[start_state]) 
    { }
    virtual ~Toggle() {  }
    bool value() {  return state==btrue;    }

    virtual Toggle& activate() {
        state = -state;
        return(*this);
    }
};

यह मामूली बदलाव समग्र गति में 5: 1 के अंतर से सुधार करता है । भले ही बेंचमार्क का उद्देश्य विधि कॉल समय को मापने का था, लेकिन वास्तव में यह जो माप रहा था वह था कि यह बीच में परिवर्तित होने का समय था intऔर bool। मैं निश्चित रूप से सहमत हूं कि मूल द्वारा दिखाई गई अक्षमता दुर्भाग्यपूर्ण है - लेकिन यह देखते हुए कि वास्तविक कोड में यह शायद ही कभी उत्पन्न होता है, और जिस आसानी से इसे तय किया जा सकता है, अगर यह उत्पन्न होता है, तो मुझे एक मुश्किल समय लगता है। इसका उतना ही अर्थ है।

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

public Toggle activate() {
this.counter += 1;
if (this.counter >= this.count_max) {
    this.state = !this.state;
    this.counter = 0;
}
return(this);
}

this.stateसीधे मैनिपुलेट करने के बजाय बेस फ़ंक्शन को कॉल करने के लिए इसे बदलने से काफी गति में सुधार होता है (हालांकि संशोधित सी 1 संस्करण के साथ रखने के लिए पर्याप्त नहीं है)।

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

मेरा खुद का अनुभव है कि समान रूप से अनुभवी प्रोग्रामर अनुकूलन के लिए समान ध्यान देते हैं, सी ++ जावा को अधिक बार नहीं - बल्कि कम से कम (इन दोनों के बीच) को हरा देगा, भाषा शायद ही कभी प्रोग्रामर्स और डिज़ाइन के रूप में उतना अंतर करेगी। जिन बेंचमार्क का हवाला दिया जा रहा है, वे हमारे लेखकों की ईमानदारी (in) क्षमता / (डिस) के बारे में अधिक बताते हैं, क्योंकि वे उन भाषाओं के बारे में करते हैं, जो वे बेंचमार्क को बताते हैं।

[संपादित करें: जैसा कि ऊपर एक जगह में निहित है, लेकिन जैसा कि मुझे शायद कभी नहीं होना चाहिए, जैसा कि मैंने कभी नहीं किया था, जो परिणाम मुझे बताए जा रहे हैं, वे हैं जो मुझे मिले ~ 5 साल पहले, मैंने C ++ और जावा कार्यान्वयन का उपयोग किया था जो उस समय चालू थे। । मैंने वर्तमान कार्यान्वयन के साथ परीक्षणों को फिर से नहीं चलाया है। हालाँकि, एक नज़र यह इंगित करता है कि कोड को ठीक नहीं किया गया है, इसलिए यह सब बदल जाता है जो कोड में समस्याओं को कवर करने के लिए संकलक की क्षमता होगी।]

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

ऐसा होने का सामान्य तरीका यह है कि जिस कोड की व्याख्या की जा रही है वह मशीन कोड की तुलना में बहुत अधिक कॉम्पैक्ट है, या यह सीपीयू पर चल रहा है जिसमें कोड कैश से बड़ा डेटा कैश है।

ऐसे मामले में, एक छोटा दुभाषिया (जैसे, एक फोर्थ कार्यान्वयन का आंतरिक दुभाषिया) पूरी तरह से कोड कैश में फिट हो सकता है, और यह जिस कार्यक्रम की व्याख्या कर रहा है वह पूरी तरह से डेटा कैश में फिट बैठता है। कैश आमतौर पर कम से कम 10 के कारक द्वारा मुख्य मेमोरी से तेज होता है, और अक्सर बहुत अधिक होता है (100 का कारक विशेष रूप से दुर्लभ नहीं है)।

इसलिए, यदि कैश N के एक कारक द्वारा मुख्य मेमोरी से तेज है, और यह प्रत्येक बाइट कोड को लागू करने के लिए एन मशीन कोड निर्देशों से कम लेता है, तो बाइट कोड को जीतना चाहिए (मैं सरल कर रहा हूं, लेकिन मुझे लगता है कि सामान्य विचार अभी भी होना चाहिए स्पष्ट होना)।


26
+1, पूर्ण ऐक। विशेष रूप से "भाषा शायद ही कभी प्रोग्रामर्स और डिज़ाइन के रूप में अधिक अंतर करेगी" - आप अक्सर उन समस्याओं के बारे में ठोकर खाएंगे जहां आप एल्गोरिथ्म को अनुकूलित कर सकते हैं, जैसे कि बिग-ओ में सुधार करना जो सर्वश्रेष्ठ संकलक की तुलना में बहुत अधिक बढ़ावा देगा।
श्नाडर

1
"यदि कोई भी इसमें शामिल बेंचमार्क को फिर से चलाने का फैसला करता है ..." नहीं! 2005 में वापस उन पुराने कार्यों को छोड़ दिया गया था और बेंचमार्क गेम में दिखाए गए कार्यों द्वारा प्रतिस्थापित किया गया था। मानक खेल मुखपृष्ठ पर दिखाई दे वर्तमान कार्यों के लिए वर्तमान कार्यक्रमों को फिर से चलाने कृपया किसी को भी कुछ कार्यक्रमों तो फिर से चलाने के लिए करना चाहता है, तो shootout.alioth.debian.org
igouy

@igouy: कुछ लोग अपने द्वारा चलाए गए बेंचमार्क से परिणामों की केवल पुष्टि / खंडन करना चाहते हैं, कम से कम सुधार के लिए आवश्यक न्यूनतम वास्तविकता के साथ उन्हें कुछ न्यूनतम संबंध देने के लिए। उसी समय, आप मूल रूप से सही हैं: विचाराधीन मानदंड इतने बुरे हैं कि केवल सबसे स्पष्ट त्रुटियों को ठीक करना बहुत मदद करने वाला नहीं है।
जेरी कॉफिन

और इसीलिए, 2005 में वापस, उन्हें त्याग दिया गया और अब बेंचमार्क गेम में दिखाए गए कार्यों द्वारा प्रतिस्थापित किया गया। जो लोग किसी भी बेहतर नहीं जानते हैं वे उन पुराने कार्यक्रमों को फिर से चलाते हैं।
इगौई

13
+1 मुझे C या Java शैली में C ++ कोडिंग करने वाले लोग पसंद नहीं हैं और फिर जावा को श्रेष्ठ बताते हैं। अस्वीकरण: मैं किसी भी भाषा को श्रेष्ठ नहीं कहता, लेकिन एक शैली में भद्दा सी ++ कोड लिखना जो दूसरी भाषा के लिए पूरी तरह से अनुकूल हो सकता है दोनों भाषाओं को तुलनीय नहीं बनाता है।
क्रिश्चियन राऊ

111

असीमित समय के साथ एक विशेषज्ञ द्वारा किया गया हाथ लुढ़का सी / सी ++ जावा की तुलना में कम से कम तेज या तेज होने वाला है। अंततः, जावा स्वयं C / C ++ में लिखा गया है, इसलिए यदि आप पर्याप्त इंजीनियरिंग प्रयास में रखने के इच्छुक हैं, तो आप निश्चित रूप से वह सब कुछ कर सकते हैं, जो जावा करता है।

हालांकि, जावा अक्सर निम्नलिखित कारणों से बहुत तेजी से निष्पादित करता है:

  • JIT संकलन - हालाँकि जावा क्लासेस को bytecode के रूप में संग्रहीत किया जाता है, लेकिन यह (आमतौर पर) JIT कंपाइलर द्वारा मूल कोड के लिए संकलित किया जाता है क्योंकि यह कार्यक्रम शुरू होता है। एक बार संकलित करने के बाद, यह शुद्ध देशी कोड है - इसलिए सैद्धांतिक रूप से यह प्रदर्शन करने की उम्मीद की जा सकती है और साथ ही साथ संकलित C / C ++ भी हो सकता है, क्योंकि यह कार्यक्रम काफी लंबे समय से चल रहा है (यानी आखिर JIT संकलन हो चुका है)
  • जावा में कचरा संग्रह बेहद तेज और कुशल है - हॉटस्पॉट जीसी शायद दुनिया में सबसे अच्छा ऑल-राउंड जीसी कार्यान्वयन है। यह सूर्य और अन्य कंपनियों द्वारा कई वर्षों के विशेषज्ञ प्रयास का परिणाम है। बहुत अधिक किसी भी जटिल मेमोरी मैनेजमेंट सिस्टम जिसे आप अपने आप को C / C ++ में रोल करते हैं, बदतर होगा। बेशक आप C / C ++ में बहुत तेज़ / हल्के बुनियादी मेमोरी प्रबंधन योजनाएं लिख सकते हैं, लेकिन वे लगभग पूर्ण GC प्रणाली के रूप में बहुमुखी नहीं होंगे। चूंकि अधिकांश आधुनिक प्रणालियों को जटिल स्मृति प्रबंधन की आवश्यकता होती है, इसलिए जावा को वास्तविक दुनिया की स्थितियों के लिए एक बड़ा लाभ है।
  • बेहतर प्लेटफ़ॉर्म टारगेटिंग - एप्लिकेशन स्टार्ट-अप (JIT संकलन आदि) के संकलन में देरी से जावा कंपाइलर इस तथ्य का लाभ उठा सकता है कि यह सटीक प्रोसेसर को जानता है जिस पर वह कार्य कर रहा है। यह कुछ बहुत ही लाभकारी अनुकूलन को सक्षम कर सकता है जिसे आप पूर्व-संकलित C / C ++ कोड में करने में सक्षम नहीं होंगे जो "सबसे कम सामान्य भाजक" प्रोसेसर निर्देश सेट को लक्षित करने की आवश्यकता है।
  • रनटाइम आँकड़े - क्योंकि जेआईटी संकलन रनटाइम पर किया जाता है, यह आंकड़े इकट्ठा कर सकता है जबकि कार्यक्रम निष्पादित कर रहा है जो बेहतर अनुकूलन (जैसे कि किसी विशेष शाखा को लिया जाता है) को जानने में सक्षम बनाता है। यह जावा JIT कंपाइलर्स को C / C ++ कंपाइलर (जो अग्रिम में सबसे अधिक संभावित शाखा को "अनुमान" करना है, एक धारणा जो अक्सर गलत हो सकती है) से बेहतर कोड का उत्पादन करने में सक्षम कर सकता है।
  • बहुत अच्छे पुस्तकालय - जावा रनटाइम में अच्छे प्रदर्शन के साथ बहुत अच्छी तरह से लिखित पुस्तकालयों की मेजबानी होती है (विशेष रूप से सर्वर-साइड अनुप्रयोगों के लिए)। अक्सर ये बेहतर होते हैं कि आप खुद को लिख सकें या C / C ++ के लिए आसानी से प्राप्त कर सकें।

साथ ही C / C ++ के भी कुछ फायदे हैं:

  • उन्नत अनुकूलन करने के लिए अधिक समय - C / C ++ संकलन एक बार किया जाता है, और इसलिए यदि आप ऐसा करने के लिए इसे कॉन्फ़िगर करते हैं तो उन्नत अनुकूलन करने में काफी समय व्यतीत कर सकते हैं। कोई सैद्धांतिक कारण नहीं है कि जावा ऐसा क्यों नहीं कर सकता है, लेकिन व्यवहार में आप जावा को जेआईटी-संकलन कोड में अपेक्षाकृत जल्दी चाहते हैं, इसलिए जेआईटी कंपाइलर "सरल" अनुकूलन पर ध्यान केंद्रित करता है।
  • निर्देश जो बाइटकोड में स्पष्ट नहीं हैं - जबकि जावा बाइटकोड पूरी तरह से सामान्य उद्देश्य है, फिर भी कुछ चीजें हैं जो आप निम्न स्तर पर कर सकते हैं जो आप बायटेकोड में नहीं कर सकते हैं (अनियंत्रित सूचक अंकगणित एक अच्छा उदाहरण है!)। इस प्रकार के टोटकों का उपयोग करके आप कुछ प्रदर्शन लाभ प्राप्त कर सकते हैं
  • कम "सुरक्षा" विरोधाभासी - जावा यह सुनिश्चित करने के लिए कुछ अतिरिक्त काम करता है कि कार्यक्रम सुरक्षित और विश्वसनीय हैं। उदाहरण सरणियों पर सीमा की जाँच, कुछ निश्चित संगणक गारंटी, अशक्त सूचक जाँच, जातियों पर प्रकार सुरक्षा आदि हैं। C / C ++ में इनसे बचकर आप कुछ प्रदर्शन लाभ प्राप्त कर सकते हैं (हालाँकि यकीनन यह एक बुरा विचार हो सकता है!)

कुल मिलाकर:

  • जावा और C / C ++ समान गति प्राप्त कर सकते हैं
  • सी / सी ++ में शायद विषम परिस्थितियों में मामूली बढ़त है (यह आश्चर्यजनक नहीं है कि एएए गेम डेवलपर्स अभी भी इसे पसंद करते हैं, उदाहरण के लिए)
  • व्यवहार में यह इस बात पर निर्भर करेगा कि आपके विशेष एप्लिकेशन के लिए शेष राशि से ऊपर सूचीबद्ध विभिन्न कारक कैसे हैं।

9
विज्ञापन "C ++ में अनुकूलन के लिए अधिक समय": यह उन ट्विक्स में से एक है जो Oracle VM तब करता है जब आपने सर्वर VM चुना था: यह लंबे समय में उच्च प्रदर्शन की अनुमति देने के लिए एक उच्च स्टार्ट-अप लागत को स्वीकार करता है। हालाँकि, क्लाइंट वीएम को इष्टतम स्टार्टअप समय के लिए ट्विक किया गया है। ताकि जावा के भीतर भी वह अंतर मौजूद हो
जोकिम सॉर

8
-1: एक C ++ कंपाइलर एक बहुत ही अनुकूलित बाइनरी को बनाने के लिए अधिक समय (घंटे, शाब्दिक, एक बड़ी लाइब्रेरी के लिए) ले सकता है। जावा JIT संकलक इतना समय नहीं ले सकता है, यहां तक ​​कि "सर्वर" संस्करण भी। मुझे गंभीरता से संदेह है कि जावा जेआईटी कंपाइलर एमएस सी ++ कंपाइलर जिस तरह से करता है, वह पूरे प्रोग्राम ऑप्टिमाइज़ेशन को करने में सक्षम होगा।
क्वांट_देव

20
@quant_dev: निश्चित रूप से, लेकिन क्या मैंने अपने उत्तर में C ++ लाभ (उन्नत अनुकूलन करने के लिए अधिक समय) के रूप में कहा है? तो क्यों -1?
मिकेरा

13
कचरा संग्रहण जावा के लिए गति का लाभ नहीं है। यदि आप C ++ प्रोग्रामर हैं जो केवल यह नहीं जानता कि आप क्या कर रहे हैं, तो यह केवल गति का लाभ है। यदि आप सब देख रहे हैं कि आप कितनी तेजी से आवंटित कर सकते हैं, तो हाँ, कचरा कलेक्टर जीत जाएगा। हालाँकि, कुल मिलाकर कार्यक्रम का प्रदर्शन, अभी भी मेमोरी को मैन्युअल रूप से प्रबंधित करके बेहतर किया जा सकता है।
बिली ओपल

4
... लेकिन C ++ के साथ, आप हमेशा सैद्धांतिक रूप से एक "JIT- जैसी परत" रख सकते हैं, जो C ++ प्रोग्राम की कच्ची गति को बनाए रखते हुए, रनटाइम पर समान शाखा अनुकूलन करता है। (सैद्धांतिक रूप से ।:()
मतीन उल्हाक

19

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


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

10
@ स्टीव ३१४: लेकिन विशुद्ध रूप से वीएम की व्याख्या करने वाले सी ++ से बेहतर नहीं होंगे, इसलिए वे वास्तव में इस प्रश्न के लिए प्रासंगिक नहीं हैं।
जोआचिम सॉर

JIT संकलक कोड के विशिष्ट उपयोग के लिए गतिशील रूप से अनुकूलन भी कर सकता है, जो कि संकलित कोड के साथ संभव नहीं है।
Starblue

2
@starblue, ठीक है, यह स्थैतिक संकलन के साथ कुछ हद तक संभव है - प्रोफ़ाइल-निर्देशित अनुकूलन देखें।
तर्क

18

सभी चीजें समान होने के कारण, आप कह सकते हैं: नहीं, जावा को कभी तेज नहीं होना चाहिए । आप हमेशा स्क्रैच से जावा को C ++ में लागू कर सकते हैं और इस तरह कम से कम अच्छा प्रदर्शन प्राप्त कर सकते हैं। व्यवहार में, हालांकि:

  • JIT अंत-उपयोगकर्ता की मशीन पर कोड संकलित करता है, जिससे यह सटीक सीपीयू के लिए अनुकूलन करने की अनुमति देता है कि वे चल रहे हैं। जबकि संकलन के लिए यहां एक ओवरहेड है, यह गहन ऐप के लिए अच्छी तरह से भुगतान कर सकता है। आपके द्वारा उपयोग किए जा रहे सीपीयू के लिए अक्सर वास्तविक जीवन कार्यक्रम संकलित नहीं किए जाते हैं।
  • जावा कंपाइलर सी ++ कंपाइलर की तुलना में चीजों को स्वचालित रूप से अनुकूलित करने में बेहतर हो सकता है। या यह नहीं हो सकता है, लेकिन वास्तविक दुनिया में, चीजें हमेशा सही नहीं होती हैं।
  • कचरा संग्रह जैसे अन्य कारकों के कारण प्रदर्शन व्यवहार भिन्न हो सकता है। C ++ में, आप आमतौर पर किसी वस्तु के साथ किए जाने पर विध्वंसक को तुरंत कॉल करते हैं। जावा में, आप केवल वास्तविक विनाश में देरी करते हुए संदर्भ जारी करते हैं। यह एक अंतर का एक और उदाहरण है जो प्रदर्शन के मामले में न तो यहां है और न ही है। बेशक, आप तर्क दे सकते हैं कि आप सी ++ में जीसी को लागू कर सकते हैं और इसके साथ किया जा सकता है, लेकिन वास्तविकता यह है कि कुछ लोग / चाहते हैं / कर सकते हैं।

एक तरफ, यह 80/90 के दशक में सी के बारे में बहस की याद दिलाता है। हर कोई सोच रहा था कि "क्या कभी विधानसभा के रूप में उपवास किया जा सकता है?"। मूल रूप से, इसका उत्तर था: कागज पर नहीं, लेकिन वास्तव में सी कंपाइलर ने 90% असेंबली प्रोग्रामर (अच्छी तरह से, यह थोड़ा परिपक्व होने के बाद) से अधिक कुशल कोड बनाया।


2
जीसी के बारे में, यह सिर्फ यह नहीं है कि जीसी वस्तुओं के विनाश में देरी कर सकता है (जो लंबी अवधि में मायने नहीं रखना चाहिए); तथ्य यह है कि आधुनिक जीसी के साथ, जावा में C ++ की तुलना में अल्पकालिक वस्तुओं का आवंटन / निपटान अत्यंत सस्ता है।
Péter Török

@ PéterTörök हाँ, आप सही हैं, अच्छी बात है।
डैनियल बी

9
@ PéterTörök लेकिन C ++ में, अल्पकालिक ऑब्जेक्ट को अक्सर स्टैक पर रखा जाता है, जो बदले में किसी भी GC-ed हीप जावा की तुलना में बहुत तेज होता है।
क्वांट_देव

@quant_dev, आप एक और महत्वपूर्ण GC प्रभाव भूल गए: जमाव। इसलिए मुझे यकीन नहीं होगा कि कौन सा रास्ता तेज है।
तर्क

3
@DonalFellows क्या आपको लगता है कि मुझे C ++ में स्मृति प्रबंधन के बारे में चिंता करना है? ज्यादातर समय मैं नहीं। ऐसे सरल पैटर्न हैं जिन्हें आपको लागू करने की आवश्यकता है, जो जावा से अलग हैं, लेकिन यह है।
क्वांट_देव

10

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

...

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

http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html


यह पूरी तस्वीर का केवल एक छोटा सा हिस्सा है, लेकिन फिर भी बहुत प्रासंगिक है।
जोकिम सॉर

2
मुझे यह पसंद है कि इसका पदार्थ कैसा है: जावा नोब्स के लिए है, जादू जीसी पर भरोसा करें, यह बेहतर जानता है।
मुर्दाघर।

1
@ मॉर्ग: या आप इसे इस तरह से पढ़ सकते हैं: जावा उन लोगों के लिए है, जो अपना समय थोड़ा ट्विडलिंग और मैनुअल मेमोरी मैनेजमेंट के साथ बर्बाद करने के बजाय चीजों को प्राप्त करना पसंद करते हैं।
Landei

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

1
@Morg मुझे यह बहुत अजीब लगता है कि आप ओएस पर ध्यान कैसे केंद्रित करते हैं। यह बस कई कारणों से एक अच्छा उपाय नहीं हो सकता। सबसे पहले, ओएस की आवश्यकताएं अधिकांश अन्य सॉफ़्टवेयर से महत्वपूर्ण रूप से भिन्न होती हैं, दूसरा आपके पास पांडा अंगूठे सिद्धांत है (जो किसी अन्य भाषा में एक पूर्ण ओएस को फिर से लिखना चाहता है, जो काम कर रहे हैं और यहां तक ​​कि मुफ्त विकल्प भी चाहते हैं?) और तीसरा अन्य सॉफ्टवेयर OS की विशेषताओं का उपयोग करता है, इसलिए कभी भी डिस्क ड्राइवर, टास्क मैनेजर, आदि लिखने की आवश्यकता नहीं है। यदि आप कुछ बेहतर तर्क नहीं दे सकते हैं (पूरी तरह से ओएस पर आधारित नहीं) तो आप एक हूटर की तरह आवाज निकालते हैं।
Landei

5

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

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

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

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


5

टिम होलोवे द्वारा JavaRanch पर पोस्ट किया गया:

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

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

स्रोत: http://www.coderanch.com/t/547458/Performance/java/Ahead-Time-vs-Just-time


3
और एक बार फिर, यह गलत / अपूर्ण है। प्रोफ़ाइल-निर्देशित ऑप्टिमाइज़ेशन वाले स्टेटिक कंपाइलर इसे पहचान सकते हैं।
कोनराड रूडोल्फ

2
कोनराड, स्थिर संकलक वर्तमान वर्कलोड के आधार पर तर्क को पलट सकते हैं? जैसा कि मैं समझता हूं, स्थिर संकलक एक बार कोड उत्पन्न करते हैं और यह हमेशा के लिए समान रहता है।
थियागो नेग्री

2
वर्तमान कार्यभार, नहीं। लेकिन ठेठ काम का बोझ। प्रोफ़ाइल-निर्देशित ऑप्टिमाइज़ेशन विश्लेषण करता है कि आपका प्रोग्राम कैसे विशिष्ट लोड के तहत चलता है और हॉटस्पॉट JIT करता है, उसी तरह हॉट-स्पॉट का अनुकूलन करता है।
कोनराड रुडोल्फ

4

ऐसा इसलिए है क्योंकि अंतिम चरण जनरेटिंग मशीन कोड पारदर्शी रूप से आपके जावा प्रोग्राम को चलाने के दौरान जेवीएम के अंदर होता है , आपके सी ++ प्रॉम के निर्माण के दौरान स्पष्ट के बजाय।

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

एक गटर को स्वचालित रूप से निष्क्रिय करने के लिए बस इतनी सी बात है कि एक मूल्य प्राप्त करने के लिए एक JUMP-RETURN की आवश्यकता नहीं है, चीजों को गति दें।

हालांकि, जिस चीज ने वास्तव में तेजी से कार्यक्रमों की अनुमति दी है वह बाद में बेहतर सफाई है। जावा में कचरा संग्रहण तंत्र सी में मैनुअल मॉलोक-फ्री की तुलना में तेज है। कई आधुनिक मॉलोक-फ्री कार्यान्वयन कचरा कलेक्टर का उपयोग करते हैं।


ध्यान दें कि यह एम्बेडेड सामान JVM को बड़ा और धीमा बनाना शुरू करता है जब तक कि बेहतर कोड को पकड़ने का मौका न हो।

1
"कई आधुनिक मलोको-फ्री कार्यान्वयन एक कचरा कलेक्टर का उपयोग करते हैं।" वास्तव में? मैं और जानना चाहूंगा; क्या आपके पास कोई संदर्भ है?
शॉन मैकमिलन

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

@ सीनमेकिलन, मैंने कुछ समय पहले मॉलॉक-मुक्त कार्यान्वयन के प्रदर्शन के बारे में एक विश्लेषण देखा था जिसमें यह उल्लेख किया गया था कि सबसे तेज़ एक कचरा कलेक्टर का इस्तेमाल किया गया था। मुझे याद नहीं है कि मैं इसे कहाँ पढ़ता हूँ।

क्या यह BDW रूढ़िवादी जीसी था?
डेमी

4

संक्षिप्त उत्तर - यह नहीं है। इसे भूल जाओ, विषय आग या पहिया जितना पुराना है। Java या .NET नहीं है और C / C ++ से तेज नहीं होगा। यह अधिकांश कार्यों के लिए पर्याप्त तेज़ है जहाँ आपको अनुकूलन के बारे में बिल्कुल भी सोचने की आवश्यकता नहीं है। रूपों और एसक्यूएल प्रसंस्करण की तरह, लेकिन यह वह जगह है जहाँ यह समाप्त होता है।

बेंचमार्क, या अक्षम डेवलपर्स द्वारा लिखी गई छोटी ऐप के लिए हां, अंतिम परिणाम यह होगा कि जावा / .NET संभवत: करीब होने वाला है और शायद इससे भी तेज।

हकीकत में, स्टैक पर मेमोरी आवंटित करना या मेमोन्स का उपयोग करने जैसी सरल चीजें बस जावा / .NET को मौके पर ही मार देंगी।

कचरा संग्रहित दुनिया सभी लेखांकन के साथ मेमोज़ोन का उपयोग कर रही है। सी और सी के लिए मेमोज़ोन जोड़ें तेजी से वहीं पर होगा। विशेष रूप से उन जावा बनाम सी "उच्च-प्रदर्शन कोड" बेंचमार्क के लिए, जो इस तरह से जाते हैं:

for(...)
{
alloc_memory//Allocating heap in a loop is verrry good, in't it?
zero_memory//Extra zeroing, we really need it in our performance code
do_stuff//something like memory[i]++
realloc//This is lovely speedup
strlen//loop through all memory, because storing string length is soo getting old
free//Java will do that outside out timing loop, but oh well, we're comparing apples to oranges here
}//loop 100000 times

सी / सी ++ (या प्लेसमेंट नए) में स्टैक आधारित चर का उपयोग करने की कोशिश करें, वे अनुवाद करते हैं sub esp, 0xff, यह एक एकल x86 निर्देश है, जिसे जावा के साथ हराया - आप नहीं कर सकते ...

ज्यादातर बार मैं उन बेंचों को देखता हूं जहां सी ++ के खिलाफ जावा की तुलना की जाती है, इससे मुझे ऐसा लगता है, जैसे? गलत मेमोरी एलोकेशन स्ट्रैटेजी, बिना भंडार के स्वयं उगने वाले कंटेनर, कई नए। यह प्रदर्शन उन्मुख C / C ++ कोड के करीब भी नहीं है।

यह भी पढ़ें: https://days2011.scala-lang.org/sites/days2011/files/ws3-1-Hundt.pdf


1
गलत। पूरी तरह से गलत है। आप अपने मैन्युअल मेमोरी प्रबंधन के साथ एक कॉम्पैक्ट जीसी को पछाड़ने में सक्षम नहीं होंगे। Naive reference count कभी भी उचित mark'n'sweep से बेहतर नहीं होगा। जैसे ही यह एक जटिल मेमोरी मैनेजमेंट की बात आती है, C ++ एक मंदबुद्धि है।
एसके-लॉजिक

3
@ एसके-लॉजिक: गलत, मेमोज़ोन या स्टैक आवंटन के साथ कोई मेमोरी आवंटन या डीललैक्शन एट ऑल है। आपके पास मेमोरी का एक ब्लॉक है और आप इसे लिखते हैं। कंसीलर प्रोटेक्शन इंटरलाकेड एक्सचेंज आदि जैसे वाष्पशील चर के साथ मुक्त रूप में मार्क ब्लॉक करें, और अगले थ्रेड को केवल ओएस पर मेमोरी के लिए जाने के बिना डेटा को प्रचारित करने के लिए डेटा डंप है, अगर यह मुफ्त है। स्टैक के साथ यह और भी आसान है, एकमात्र अपवाद है कि आप स्टैक पर 50MB डंप नहीं कर सकते हैं। और वह वस्तु जीवनकाल केवल {} के अंदर है।
कोडर

2
@ एसके-लॉजिक: कंपाइलर पहले शुद्धता, प्रदर्शन दूसरे। खोज इंजन, डेटाबेस इंजन, रीयल-टाइम ट्रेडिंग सिस्टम, गेम वह हैं जो मैं प्रदर्शन को महत्वपूर्ण मानूंगा। और उनमें से अधिकांश चपटे संरचनाओं पर निर्भर हैं। और तो और, कंपाइलर ज्यादातर C / C ++ में लिखे जाते हैं। कस्टम आवंटनकर्ताओं के साथ मुझे लगता है। तो फिर, मैं पेड़ या rammap पर सूची तत्वों का उपयोग करने के साथ कोई समस्या नहीं देखते हैं। आप बस प्लेसमेंट नए का उपयोग करें। उसमें बहुत जटिलता नहीं है।
कोडर

3
@ एसके-लॉजिक: यह बहुत तेज़ नहीं है, मैंने जो भी .NET / Java ऐप देखा है, वह हमेशा धीमा और वास्तविक हॉग रहा है। SANE C / C ++ कोड में प्रबंधित ऐप के हर पुनर्लेखन के परिणामस्वरूप क्लीनर और लाइटर ऐप बन गए। प्रबंधित ऐप्स हमेशा भारी होते हैं। VS2010 बनाम 2008 देखें। समान डेटा संरचनाएं, लेकिन VS2010 एक HOG है। सही ढंग से लिखा C / C ++ ऐप्स आमतौर पर मिलीसेकंड में बूट होता है, और स्प्लैश स्क्रीन पर अटक नहीं जाता है, जबकि बहुत कम मेमोरी का उपभोग करता है। केवल नकारात्मक पक्ष यह है कि आपको हार्डवेयर को ध्यान में रखते हुए कोड करना होगा, और बहुत से लोग नहीं जानते कि यह आजकल कैसे है। यह केवल बेंचमार्क है जहां प्रबंधित एक मौका है।
कोडर

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

2

वास्तविकता यह है कि वे दोनों केवल उच्च स्तर के असेंबलर हैं जो वास्तव में वही करते हैं जो प्रोग्रामर उन्हें बताता है, अतिशयोक्ति है कि प्रोग्रामर उन्हें सटीक क्रम में कैसे बताता है जो प्रोग्रामर उन्हें बताता है। प्रदर्शन अंतर इतने छोटे होते हैं कि सभी व्यावहारिक उद्देश्यों के लिए असंगत हो जाते हैं।

भाषा "धीमी" नहीं है, प्रोग्रामर ने एक धीमा कार्यक्रम लिखा। बहुत कम ही किसी प्रोग्राम को एक भाषा के आउटपरफ्रॉम (किसी भी व्यावहारिक उद्देश्य के लिए) में सबसे अच्छा तरीका लिखा जाता है, एक प्रोग्राम वैकल्पिक भाषा के सर्वोत्तम तरीके का उपयोग करके एक ही काम करता है, जब तक कि अध्ययन का लेखक अपने विशेष कुल्हाड़ी को पीसने के लिए बाहर न हो।

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


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

2

निम्नलिखित लिंक देखें ... लेकिन यह कैसे भी संभव है? यह मेरे दिमाग को चकित करता है कि बाईटेकोड की व्याख्या कभी भी संकलित भाषा से तेज हो सकती है।

  1. क्या वे ब्लॉग पोस्ट भरोसेमंद सबूत प्रदान करते हैं?
  2. क्या वे ब्लॉग पोस्ट निश्चित प्रमाण प्रदान करते हैं?
  3. क्या वे ब्लॉग पोस्ट "व्याख्या किए गए बायटेकोड" के बारे में भी प्रमाण प्रदान करते हैं?

कीथ ले आपको बताता है कि "स्पष्ट दोष" हैं लेकिन उन "स्पष्ट दोषों" के बारे में कुछ भी नहीं है। 2005 में वापस उन पुराने कार्यों को छोड़ दिया गया था और बेंचमार्क गेम में दिखाए गए कार्यों द्वारा प्रतिस्थापित किया गया था

कीथ ले आपको बताता है कि उसने "अब पुरानी पुरानी कंप्यूटर लैंग्वेज शूटआउट से C ++ और जावा के लिए बेंचमार्क कोड लिया और परीक्षण चलाया" लेकिन वास्तव में वह केवल उन पुराने परीक्षणों में से 25 में से 14 के लिए माप दिखाता है

कीथ ले अब आपको बताता है कि वह सात साल पहले ब्लॉग पोस्ट के साथ कुछ भी साबित करने की कोशिश नहीं कर रहा था, लेकिन फिर उसने कहा "मैं लोगों को यह कहते हुए सुनने से बीमार था कि जावा धीमा था, जब मुझे पता है कि यह बहुत तेज़ है ..." जो बताता है वापस तो कुछ था जो वह साबित करने की कोशिश कर रहा था।

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

क्या 25 छोटे छोटे कार्यक्रमों के माप भी निश्चित प्रमाण प्रदान करते हैं?

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


-1

यह मुझे विस्मित करता है कि "व्याख्याकृत बायटेकोड" की यह अजीब धारणा कितनी व्यापक है। क्या आप लोगों ने कभी जेआईटी-संकलन के बारे में सुना है? आपका तर्क जावा पर लागू नहीं किया जा सकता।

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


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

@thiton, संभावना है कि आपके अपने CS-fu थोड़े कमजोर हैं। JVM (हॉट स्पॉट के लिए) व्याख्या के किसी भी प्रकार नहीं करता है - कोई है जो सीएस उल्लेख करने की हिम्मत के रूप में, आप के लिए है पता करने के लिए इसका क्या मतलब है, और कैसे एक व्याख्या की एक संचालन अर्थ विज्ञान एक देशी कोड चलाने से अलग है। लेकिन, संभावना है, आप बस व्याख्या से संकलन को अलग करने के लिए सीएस के लिए पर्याप्त नहीं जानते हैं।
तर्क

2
उम्म, लेकिन बाईटेकोड, को चलाने के लिए, मूल कोड में परिवर्तित करना होगा - आप सीपीयू को जावा बायटेकोड नहीं खिला सकते हैं। अतः आकार तर्क अमान्य है।
क्वांट_देव

@quant_dev, निश्चित रूप से - मैंने कहा कि यह मामला पूरी तरह से JVM से असंबंधित है। आपको उस प्रभाव को काम करने के लिए बहुत सरल बायोटेक इंजन की आवश्यकता होगी।
एसके-तर्क

-1

JIT, GC और एक तरफ, C ++ बहुत ही आसानी से जावा की तुलना में बहुत अधिक सुस्त बना दिया जा सकता है। यह बेंचमार्क में नहीं दिखाई देगा, लेकिन जावा डेवलपर और C ++ डेवलपर द्वारा लिखे गए समान ऐप जावा में बहुत तेज हो सकते हैं।

  • ऑपरेटर ओवरलोडिंग। प्रत्येक सरल ऑपरेटर जैसे "+" या "=" कोड की सैकड़ों पंक्तियों को सुरक्षा जाँच, डिस्क संचालन, लॉगिंग, ट्रैकिंग और प्रोफाइलिंग कह सकते हैं। और उनका उपयोग करना इतना आसान है कि एक बार जब आप ऑपरेटरों को अधिभारित करते हैं, तो आप उन्हें स्वाभाविक रूप से और प्रचुरता से उपयोग करते हैं और ध्यान दिए बिना कि कैसे उपयोग ढेर हो जाता है।
  • टेम्पलेट्स। ये मेमोरी जितनी स्पीड को प्रभावित नहीं करते हैं। टेम्प्लेट्स के अनजाने उपयोग से आपको बिना किसी सूचना के कोड की लाखों लाइनें (मूल टेम्प्लेट के लिए विकल्प) उत्पन्न करने की ओर ले जाएगा। लेकिन फिर बाइनरी लोडिंग समय, मेमोरी उपयोग, स्वैप उपयोग - यह सब बेंचमार्क के खिलाफ भी काम करता है। और रैम का उपयोग छत के माध्यम से होता है।

उन्नत वंशानुक्रम पैटर्न के लिए, ये बहुत समान हैं - C ++ में कुछ हैं जो जावा नहीं करता है और इसके विपरीत, लेकिन उनमें से सभी समान, महत्वपूर्ण ओवरहेड भी पेश करते हैं। तो वस्तु-भारी प्रोग्रामिंग में कोई विशेष C ++ लाभ नहीं।

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


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

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

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

1
चतुर सवाल। मैं यह बिल्कुल भी अनुमान नहीं लगाऊंगा, मैं मापूंगा, फिर अभिनय करूंगा । मुझे उस युक्ति से कभी कोई समस्या नहीं थी।
कोनराड रुडोल्फ

1
@KonradRudolph: यह सब सच है जब यह स्पष्टता और कोड लिखने में आसानी होती है, जिससे यह बग-मुक्त और रखरखाव योग्य हो जाता है। एल्गोरिथ्म कार्यान्वयन की दक्षता के बारे में बात अभी भी हालांकि खड़ी है: यदि आप obj.fetchFromDatabase("key")एक ही कुंजी के लिए कोड की पांच पंक्तियों के भीतर तीन बार लिखने वाले हैं , तो आप दो बार सोचेंगे कि क्या उस मूल्य को एक बार प्राप्त करना है और इसे स्थानीय चर में कैश करना है। यदि आप डेटाबेस लाने के रूप में कार्य करने के लिए अधिभार के obj->"key"साथ लिखते हैं ->, तो आप इसे और अधिक पास होने के लिए प्रवण हैं क्योंकि ऑपरेशन की लागत स्पष्ट नहीं है।
एसएफ।

-2

किसी तरह स्टैक एक्सचेंज मेरे अन्य स्टैकपॉइंट्स को नहीं लेता है ... दुर्भाग्य से कोई उत्तर नहीं ...

हालाँकि यहाँ दूसरा सबसे अधिक मत दिया गया उत्तर मेरी विनम्र राय में गलत जानकारी से भरा है।

C / C ++ में एक विशेषज्ञ द्वारा एक हाथ से लुढ़का ऐप हमेशा एक जावा एप्लिकेशन, अवधि की तुलना में बहुत तेज होने वाला है। वहाँ 'के रूप में उपवास के रूप में जावा या तेज़' नहीं है। यह आपके द्वारा ठीक किए गए आइटमों के कारण ठीक ठीक तेज़ है:

JIT संकलन : क्या आप वास्तव में एक स्वत: ऑप्टिमाइज़र की अपेक्षा करते हैं कि एक विशेषज्ञ प्रोग्रामर के स्मार्ट होने और इरादे और कोड के बीच लिंक को देखने के लिए सीपीयू वास्तव में चलने वाला है ??? इसके अलावा, आप जो भी JIT करते हैं वह पहले से संकलित प्रोग्राम की तुलना में समय गंवा देता है।

कचरा संग्रह एक ऐसा साधन है जो केवल संसाधनों को डील करता है जो एक प्रोग्रामर को अधिक कुशल तरीके से डील करने के लिए भूल गया होगा।

जाहिर है कि यह केवल एक विशेषज्ञ (आपने पद को चुना) की तुलना में धीमा हो सकता है सी प्रोग्रामर अपनी मेमोरी को संभालने के लिए करेगा (और सही तरीके से लिखे गए ऐप में कोई लीक नहीं हैं)।

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

रनटाइम सांख्यिकी यह मेरे ज्ञान से परे है, लेकिन मुझे संदेह है कि सी में एक विशेषज्ञ के पास पर्याप्त शाखा पूर्वानुमान ज्ञान से अधिक है जो फिर से स्वचालित अनुकूलन को आउटसोर्स कर सकता है -

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

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

कुल मिलाकर:

जावा कभी भी CV / C ++ की गति तक नहीं पहुँच सकता है क्योंकि यह JVM में बहुत अधिक सुरक्षा, सुविधाओं और उपकरणों के साथ काम करता है।

C ++ में अनुकूलित सॉफ़्टवेयर में एक निश्चित स्पष्ट बढ़त है, यह कंप्यूटिंग या गेम्स के लिए हो, और यह देखने के लिए सामान्य है कि C ++ कार्यान्वयन इस बिंदु पर कोडिंग प्रतियोगिता जीतते हैं कि सबसे अच्छा जावा कार्यान्वयन केवल दूसरे पृष्ठ पर देखा जा सकता है।

व्यवहार में C ++ एक खिलौना नहीं है और आपको कई गलतियों से दूर नहीं होने देगा जो कि अधिकांश आधुनिक भाषाएं संभाल सकती हैं, हालांकि सरल और कम सुरक्षित होने के कारण, यह स्वाभाविक रूप से तेज़ है।

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


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

4
यह उत्तर इस बारे में गलत धारणाओं से भरा है कि आधुनिक आशावादी क्या कर सकते हैं। हाथ से अनुकूलित कोड उस के खिलाफ एक मौका खड़ा नहीं करता है। लेकिन फिर, C ++ में एक अनुकूलन संकलनकर्ता भी है।
कोनराड रुडोल्फ

आपकी टिप्पणी के लिए धन्यवाद एसके-तर्क, लेकिन जैसा कि आप इसे कहते हैं, जीसी सामान्य रूप से बहुत तेज हो सकता है, हम बात कर रहे हैं कि किसी विशेष मामले में सबसे तेज क्या होगा, और अच्छी तरह से यह लगता है कि ज्यादातर लोग सहमत हैं कि जीसी कुछ भी कर सकते हैं एक प्रोग्रामर कर सकता है, और इससे भी बेहतर। निश्चित रूप से आप ऑब्जेक्ट्स को मैन्युअल रूप से स्थानांतरित कर सकते हैं जब आपके पास डायरेक्ट मेमोरी एक्सेस हो .. lol। JVM इंटर्नल का मेरा ज्ञान निश्चित रूप से सीमित है और मुझे उम्मीद है कि जावा-हेड्स मुझे प्रकाश दिखाने की कोशिश करेंगे, न कि मुझे जीसी के बारे में यादृच्छिक बकवास बताएं कि जो सामान करने में सक्षम है वह मैन्युअल रूप से नहीं कर सकता है (योग्य ... जीसी के लिए भी CPU निर्देशों का उपयोग करें;))।
मुर्दाघर।

कोनराड, मैं मानता हूं कि मैं काफी हद तक आधुनिक आशावादियों को कम आंक रहा हूं ... हालांकि मुझे यह दिलचस्प लगता है कि आप हाथ से अनुकूलित कोड को ऑटो-अनुकूलित कोड से नीच मानते हैं। आप क्या उम्मीद करते हैं कि कंपाइलर यह देख सके कि मानव नहीं कर सकता है?
मुर्दाघर।

1
सही । -1 पुश करते रहें, यह इस तथ्य को नहीं बदलेगा कि C ++ जावा से तेज है। मैं आधुनिक संकलक के बारे में बहुत कुछ नहीं जानता, लेकिन इससे मुख्य बिंदु पर कोई फर्क नहीं पड़ता है, जो कि सही है और यहां सबसे अधिक मतदान वाले उत्तर का खंडन करता है। क्यों और क्या सी ++ एचपीसी के लिए उनके GPU पर nVidia के लिए एक प्राथमिकता होगी। अन्य सभी गेम C ++ में क्यों लिखे जाएंगे, हर एक DB इंजन C में क्यों लिखा जाएगा?
मुर्दाघर।

-4

मैंने जावा में कम से कम दो प्रभावशाली विजुअल्स को देखा है, यह कहना कि खेलों के लिए तेजी से पर्याप्त नहीं है एक मिथ्या नाम है। सिर्फ इसलिए कि गेम डिज़ाइनर C ++ को अन्य भाषाओं से अधिक पसंद करते हैं, कहते हैं कि यह सिर्फ जावा से संबंधित नहीं है, इसका मतलब सिर्फ यह है कि प्रोग्रामर ने वास्तव में किसी भी अन्य प्रोग्रामिंग भाषाओं / प्रतिमानों के साथ डब नहीं किया है। किसी भी भाषा में सी / सी ++ या यहां तक ​​कि जावा के रूप में उन्नत कुछ भी कोड का उत्पादन कर सकता है जो तकनीकी रूप से गति तर्क को पूरा या पराजित कर सकता है। सभी अच्छी तरह से और कहा जाता है कि प्रोग्रामर क्या जानते हैं, कौन सी टीमें सबसे अधिक महत्वपूर्ण काम करती हैं और क्यों वे उक्त साधनों का उपयोग करती हैं। चूंकि हम प्रोग्रामिंग के खेल विकास के पहलू से निपट रहे हैं, तो तर्क के लिए अधिक होना चाहिए। सीधे शब्दों में कहें ' सभी के लिए पैसे और समय के बारे में क्यूए और वास्तविक दुनिया में मिलने वाले उपकरणों का उपयोग करके सेट किए गए किसी व्यवसाय के मृत समय के लिए जावा और किसी अन्य भाषा पर C ++ चुनने के लिए xx कारणों पर कोई भार नहीं है। यह सिर्फ एक बड़े पैमाने पर उत्पादन का निर्णय है। कंप्यूटिंग एल्गोरिदम के सबसे बुनियादी स्तर पर हम सभी के साथ खेल रहे हैं और शून्य हैं, गति तर्क गेमिंग में लागू किए गए सबसे विनम्र तर्कों में से एक है। यदि आप गति प्राप्त करना चाहते हैं तो बुरी तरह से प्रोग्रामिंग भाषाओं को पूरी तरह से छोड़ दें और विधानसभा के साथ काम करें जो संभवतः अब तक का सबसे अच्छा लाभ है।


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