JIT बनाम स्टेटिक कंपाइलर
जैसा कि पहले ही पोस्ट में कहा जा चुका है, JIT IL / bytecode को रनटाइम में देशी कोड में संकलित कर सकता है। उस की लागत का उल्लेख किया गया था, लेकिन इसके निष्कर्ष के लिए नहीं:
JIT की एक बड़ी समस्या यह है कि यह सब कुछ संकलित नहीं कर सकता है: JIT संकलन में समय लगता है, इसलिए JIT कोड के केवल कुछ हिस्सों को संकलित करेगा, जबकि एक स्थिर संकलक एक पूर्ण देशी बाइनरी का उत्पादन करेगा: कुछ प्रकार के कार्यक्रमों के लिए, स्थैतिक कंपाइलर बस आसानी से JIT से आगे निकल जाएगा।
बेशक, C # (या जावा, या VB) आमतौर पर C ++ की तुलना में व्यवहार्य और मजबूत समाधान का उत्पादन करने के लिए तेज़ है (यदि केवल इसलिए कि C ++ में जटिल शब्दार्थ है, और C ++ मानक पुस्तकालय है, जबकि दिलचस्प और शक्तिशाली, पूर्ण की तुलना में काफी खराब है। .NET या जावा से मानक पुस्तकालय का दायरा), इसलिए आमतौर पर, C ++ और .NET या Java JIT के बीच का अंतर अधिकांश उपयोगकर्ताओं को दिखाई नहीं देगा, और उन बायनेरिज़ के लिए जो महत्वपूर्ण हैं, ठीक है, आप अभी भी C ++ प्रोसेसिंग को कॉल कर सकते हैं। C # या Java से (भले ही इस तरह के देशी कॉल अपने आप में काफी महंगे हो सकते हैं ...)
सी ++ मेटाप्रोग्रामिंग
ध्यान दें कि आमतौर पर, आप C ++ रनटाइम कोड की तुलना C # या Java में इसके समकक्ष कर रहे हैं। लेकिन C ++ में एक विशेषता है जो जावा / C # को बॉक्स से बाहर कर सकती है, वह है टेम्पलेट मेटाप्रोग्रामिंग: कोड प्रसंस्करण को संकलन समय पर किया जाएगा (इस प्रकार, बहुत अधिक संकलन समय बढ़ जाता है), जिसके परिणामस्वरूप शून्य (या लगभग शून्य) रनटाइम होता है।
मैंने अभी तक इस पर एक वास्तविक जीवन प्रभाव देखा है (मैं केवल अवधारणाओं के साथ खेला था, लेकिन तब तक, अंतर जेआईटी के लिए निष्पादन की सेकंड और सी ++ के लिए शून्य था ), लेकिन यह ध्यान देने योग्य है, तथ्य टेम्पलेट मेटाप्रोग्रामिंग के साथ नहीं है तुच्छ...
2011-06-10 संपादित करें: C ++ में, प्रकारों के साथ खेलना संकलन समय पर किया जाता है, जिसका अर्थ है जेनेरिक कोड का उत्पादन करना जो नॉन-जेनेरिक कोड कहता है (जैसे स्ट्रिंग से टाइप टी के लिए एक जेनेरिक पार्सर, टाइप T के लिए मानक लाइब्रेरी API कॉल करना यह पहचानता है,) और पार्सर को अपने उपयोगकर्ता द्वारा आसानी से एक्स्टेंसिबल बनाना) बहुत आसान और बहुत ही कुशल है, जबकि जावा या सी # में समतुल्य लिखना सबसे अच्छा है, और हमेशा धीमी गति से हल किया जाएगा और यहां तक कि जब प्रकार संकलित समय पर ज्ञात होते हैं, तब भी मतलब आपकी पूरी उम्मीद है कि JIT पूरी बात को इनलाइन कर दे।
...
2011-09-20 को संपादित करें: ब्लिट्ज ++ ( होमपेज , विकिपीडिया ) के पीछे की टीम इस तरह से चली गई, और जाहिर है, उनका लक्ष्य वैज्ञानिक गणना पर फोरट्रान के प्रदर्शन तक पहुंचने के लिए है, जितना संभव हो सके रनटाइम निष्पादन से संकलन समय तक, C ++ टेम्पलेट के माध्यम से । तो " मैं अभी तक तो एक वास्तविक जीवन प्रभाव इस पर देख चुके हैं हिस्सा मैंने ऊपर लिखा था" जाहिरा तौर पर करता है वास्तविक जीवन में मौजूद।
मूल C ++ मेमोरी उपयोग
C ++ में Java / C # से अलग एक मेमोरी उपयोग है, और इस प्रकार, इसके अलग-अलग फायदे / दोष हैं।
JIT ऑप्टिमाइज़ेशन से कोई फर्क नहीं पड़ता है, मेमोरी में डायरेक्ट पॉइंटर एक्सेस के रूप में तेजी से कुछ भी नहीं होगा (चलो एक पल प्रोसेसर कैश के लिए अनदेखा करें, आदि)। इसलिए, यदि आपके पास मेमोरी में सन्निहित डेटा है, तो इसे C ++ पॉइंटर्स (यानी C पॉइंटर्स ... लेट सीजर को इसके कारण के माध्यम से एक्सेस करना) जावा / सी # की तुलना में कई गुना तेजी से जाएगा। और C ++ में RAII है, जो C # या जावा में भी बहुत अधिक प्रसंस्करण को आसान बनाता है। C ++ using
को अपनी वस्तुओं के अस्तित्व की गुंजाइश की आवश्यकता नहीं है। और C ++ में एक finally
क्लॉज नहीं है । यह एक त्रुटि नहीं है।
:-)
और सी # आदिम-जैसी संरचनाओं के बावजूद, सी + "स्टैक पर" वस्तुओं को आवंटन और विनाश पर कुछ भी खर्च नहीं होगा, और सफाई करने के लिए एक स्वतंत्र धागे में काम करने के लिए जीसी की आवश्यकता नहीं होगी।
मेमोरी फ़्रेग्मेंटेशन के लिए, 2008 में मेमोरी एलोकेटर्स 1980 से पुराने मेमोरी एलोकेटर्स नहीं हैं, जो आमतौर पर जीसी के साथ तुलना की जाती हैं: सी ++ आवंटन को मेमोरी में स्थानांतरित नहीं किया जा सकता है, सच है, लेकिन फिर, लिनक्स फाइल सिस्टम की तरह: हार्ड डिस्क की आवश्यकता किसे है विखंडन जब विखंडन नहीं होता है? सही कार्य के लिए सही आवंटनकर्ता का उपयोग करना C ++ डेवलपर टूलकिट का हिस्सा होना चाहिए। अब, आवंटनकर्ताओं को लिखना आसान नहीं है, और फिर, हम में से अधिकांश के पास करने के लिए बेहतर चीजें हैं, और अधिकांश उपयोग के लिए, आरएआईआई या जीसी पर्याप्त से अधिक है।
2011-10-04 को संपादित करें: कुशल आवंटनकर्ताओं के बारे में उदाहरणों के लिए: विस्टा के बाद से, विंडोज प्लेटफॉर्म पर, कम फ्रैग्मेंटेशन हीप डिफ़ॉल्ट रूप से सक्षम है। पिछले संस्करणों के लिए, LFH को WinAPI फ़ंक्शन HeapSetInformation ) पर कॉल करके सक्रिय किया जा सकता है । अन्य ओएस पर, वैकल्पिक आवंटन प्रदान किए जाते हैं (देखेंएक सूची के लिए https://secure.wikimedia.org/wikipedia/en/wiki/Malloc )
अब, मेमोरी मॉडल कुछ हद तक मल्टीकोर और मल्टीथ्रेडिंग प्रौद्योगिकी के उदय के साथ जटिल होता जा रहा है। इस क्षेत्र में, मुझे लगता है कि .NET का लाभ है, और जावा, मुझे बताया गया था, ऊपरी जमीन पर कब्जा कर लिया गया है। यह कुछ "नंगे धातु" हैकर के लिए "मशीन के पास" उसकी प्रशंसा करने के लिए आसान है। लेकिन अब, संकलक को अपनी नौकरी देने की तुलना में हाथ से बेहतर विधानसभा का निर्माण करना काफी कठिन है। सी ++ के लिए, संकलक एक दशक से आमतौर पर हैकर से बेहतर हो गया। C # और Java के लिए, यह और भी आसान है।
फिर भी, नया मानक C ++ 0x, C ++ कंपाइलरों के लिए एक सरल मेमोरी मॉडल लागू करेगा, जो C ++ में प्रभावी मल्टीप्रोसेसिंग / समानांतर / थ्रेडिंग कोड को मानकीकृत (और सरल करेगा), और अनुकूलन को आसान और कंपाइलर के लिए सुरक्षित बनाता है। लेकिन फिर, हम कुछ वर्षों में देखेंगे कि अगर इसके वादे सच होते हैं।
C ++ / CLI बनाम C # / VB.NET
नोट: इस खंड में, मैं C ++ / CLI के बारे में बात कर रहा हूँ, अर्थात, C ++ .NET द्वारा होस्ट किया गया है, न कि मूल C ++।
पिछले हफ्ते, मेरे पास .NET ऑप्टिमाइज़ेशन पर एक प्रशिक्षण था, और पता चला कि स्थिर संकलक वैसे भी बहुत महत्वपूर्ण है। जेआईटी से ज्यादा महत्वपूर्ण।
C ++ / CLI (या इसके पूर्वज, प्रबंधित C ++) में संकलित बहुत समान कोड C # (या VB.NET, जिसका कंपाइलर C # की तुलना में समान IL) का उत्पादन करता है, उसी कोड से कई गुना तेज हो सकता है।
क्योंकि C ++ स्टेटिक कंपाइलर C # की तुलना में पहले से ही अनुकूलित कोड का उत्पादन करने के लिए बहुत बेहतर था।
उदाहरण के लिए, .NET में फ़ंक्शन इनलाइनिंग उन फ़ंक्शंस तक सीमित है, जिनकी बाइटकोड लंबाई में 32 बाइट्स से कम या बराबर है। तो, C # में कुछ कोड 40 बाइट्स एक्सेसर का उत्पादन करेगा, जो कभी भी JIT द्वारा इनबिल्ड नहीं किया जाएगा। C ++ / CLI में समान कोड 20 बाइट्स एक्सेसर का उत्पादन करेगा, जो कि JIT द्वारा इनबिल्ट किया जाएगा।
एक अन्य उदाहरण अस्थायी चर है, जो सी + कंपाइलर द्वारा अभी भी संकलित किए गए हैं जबकि अभी भी सी / कंपाइलर द्वारा निर्मित आईएल में उल्लेख किया गया है। C ++ स्टैटिक कंप्लायंस ऑप्टिमाइज़ेशन के परिणामस्वरूप कम कोड आएगा, इस प्रकार फिर से अधिक आक्रामक JIT ऑप्टिमाइज़ेशन को अधिकृत करता है।
इसका कारण सी ++ देशी कंपाइलर से विशाल अनुकूलन तकनीकों से संबंधित सी ++ / सीएलआई संकलक होने का अनुमान लगाया गया था।
निष्कर्ष
मुझे C ++ बहुत पसंद है।
लेकिन जहां तक मैं इसे देखता हूं, सी # या जावा सभी एक बेहतर शर्त में हैं। इसलिए नहीं कि वे C ++ से तेज़ हैं, बल्कि इसलिए कि जब आप उनके गुणों को जोड़ते हैं, तो वे अधिक उत्पादक होते हैं, कम प्रशिक्षण की आवश्यकता होती है, और C ++ की तुलना में अधिक पूर्ण मानक पुस्तकालय होते हैं। और अधिकांश कार्यक्रमों के लिए, उनकी गति अंतर (एक तरह से या किसी अन्य में) नगण्य होगी ...
संपादित करें (2011-06-06)
C # /। NET पर मेरा अनुभव
मेरे पास अब लगभग 5 महीने का है विशेष एक्सक्लूसिव प्रोफेशनल C # कोडिंग (जो C CV और Java से पहले ही मेरे CV में जुड़ जाता है, और C ++ / CLI का एक टच)।
मैंने WinForms (अहम ...) और WCF (कूल!), और WPF (कूल !!!! दोनों XAML और रॉ C # के माध्यम से खेला है। इतना आसान है कि मुझे विश्वास है कि स्विंग सिर्फ इसकी तुलना नहीं कर सकता), और C [4.0]।
निष्कर्ष यह है कि C ++ की तुलना में C # / Java में काम करने वाले कोड का निर्माण करना आसान / तेज है, लेकिन C ++ की तुलना में C # (और जावा में भी कठिन) में एक मजबूत, सुरक्षित और मजबूत कोड का उत्पादन करना बहुत कठिन है। कारण समाप्त हो जाते हैं, लेकिन इसे संक्षेप में प्रस्तुत किया जा सकता है:
- जेनरिक टेम्प्लेट की तरह शक्तिशाली नहीं हैं ( एक कुशल जेनेरिक पार्स विधि लिखने की कोशिश करें (स्ट्रिंग से टी तक), या बढ़ावा देने के लिए एक कुशल समकक्ष :: समस्या को समझने के लिए C # में lexical_cast )
- आरए II बेजोड़ बनी हुई है ( जीसी अभी भी लीक कर सकते हैं (हाँ, मुझे लगता है कि समस्या को संभालने के लिए किया था) और केवल स्मृति को संभाल लेंगे। यहां तक कि सी # के
using
आसान और शक्तिशाली रूप में नहीं है, क्योंकि एक सही निपटान कार्यान्वयन लेखन मुश्किल है )
- C #
readonly
और Java final
C ++ के रूप में कहीं भी उपयोगी नहीं हैconst
( कोई ऐसा तरीका नहीं है कि आप जबरदस्त काम के बिना C # में आसानी से जटिल डेटा (नोड्स का एक पेड़, उदाहरण के लिए) को उजागर कर सकते हैं, जबकि यह C ++ की अंतर्निहित विशेषता है। अपरिवर्तनीय डेटा एक दिलचस्प समाधान है। , लेकिन सब कुछ अपरिवर्तनीय नहीं बनाया जा सकता है, इसलिए यह अभी तक पर्याप्त नहीं है )।
इसलिए, C # जब तक आप काम करते हैं, तब तक एक सुखद भाषा बनी रहती है, लेकिन एक निराशाजनक भाषा जिस क्षण आप कुछ चाहते हैं जो हमेशा और सुरक्षित रूप से काम करता है।
जावा और भी अधिक निराशाजनक है, क्योंकि इसमें C # की समान समस्याएं हैं, और अधिक: C # के using
कीवर्ड के समतुल्य कमी , मेरे एक कुशल सहयोगी ने बहुत अधिक समय खर्च करके यह सुनिश्चित किया है कि इसके संसाधन जहां सही तरीके से मुक्त हुए हैं, जबकि C ++ में समकक्ष होगा। आसान हो गया (विध्वंसक और स्मार्ट पॉइंटर्स का उपयोग करके)।
इसलिए मुझे लगता है कि अधिकांश कोड के लिए C # / Java का उत्पादकता लाभ दिखाई देता है ... जिस दिन तक आपको कोड की आवश्यकता होती है, जितना संभव हो उतना सही है। उस दिन, आपको दर्द का पता चल जाएगा। (आपको विश्वास नहीं होगा कि हमारे सर्वर और GUI ऐप्स से क्या पूछा गया है ...)।
सर्वर-साइड जावा और C ++ के बारे में
मैंने सर्वर टीमों के साथ संपर्क बनाए रखा (मैंने जीयूआई टीम में वापस आने से पहले उनके बीच 2 साल काम किया), इमारत के दूसरी तरफ, और मैंने कुछ दिलचस्प सीखा।
पिछले वर्षों में, प्रवृत्ति थी कि जावा सर्वर एप्स को पुराने C ++ सर्वर एप्स को बदलने के लिए नियत किया जाता है, क्योंकि जावा में बहुत सारे फ्रेमवर्क / टूल हैं, और इनका रखरखाव, तैनाती आदि करना आसान है।
... जब तक कम-विलंबता की समस्या ने पिछले महीनों में अपने बदसूरत सिर को पाला। फिर, जावा सर्वर ऐप, हमारे कुशल जावा टीम द्वारा किए गए अनुकूलन का कोई फर्क नहीं पड़ता, बस और साफ-सुथरे तरीके से पुराने के खिलाफ दौड़ हार गए, वास्तव में अनुकूलित नहीं C ++ सर्वर।
वर्तमान में, निर्णय यह है कि जावा सर्वर को आम उपयोग के लिए रखा जाए, जहां प्रदर्शन अभी भी महत्वपूर्ण है, कम-विलंबता लक्ष्य से चिंतित नहीं है, और कम-विलंबता और अल्ट्रा-कम-विलंबता जरूरतों के लिए पहले से तेज C ++ सर्वर अनुप्रयोगों को आक्रामक रूप से अनुकूलित करता है।
निष्कर्ष
उम्मीद के मुताबिक कुछ भी सरल नहीं है।
जावा, और यहां तक कि अधिक सी #, शांत भाषा हैं, व्यापक मानक पुस्तकालयों और चौखटे के साथ, जहां आप तेजी से कोड कर सकते हैं, और बहुत जल्द परिणाम आ सकते हैं।
लेकिन जब आपको कच्ची शक्ति, शक्तिशाली और व्यवस्थित अनुकूलन, मजबूत संकलक समर्थन, शक्तिशाली भाषा सुविधाएँ और पूर्ण सुरक्षा की आवश्यकता होती है, तो जावा और C # आपको गुणवत्ता के अंतिम लापता लेकिन महत्वपूर्ण खतरों को जीतने के लिए कठिन बनाते हैं जो आपको प्रतियोगिता से ऊपर रहने की आवश्यकता है।
ऐसा लगता है जैसे आपको C ++ की तुलना में C # / Java में कम समय और कम अनुभवी डेवलपर्स की आवश्यकता थी, औसत गुणवत्ता कोड का उत्पादन करने के लिए, लेकिन दूसरी ओर, जिस क्षण आपको उत्तम गुणवत्ता कोड के लिए उत्कृष्ट की आवश्यकता थी, परिणाम प्राप्त करने के लिए यह अचानक आसान और तेज था। C ++ में सही है।
बेशक, यह मेरी अपनी धारणा है, शायद हमारी विशिष्ट आवश्यकताओं तक सीमित है।
लेकिन फिर भी, यह वही है जो आज जीयूआई टीमों और सर्वर-साइड टीमों में होता है।
अगर कुछ नया होता है, तो बेशक मैं इस पोस्ट को अपडेट करूंगा।
संपादित करें (2011-06-22)
"हम पाते हैं कि प्रदर्शन के संबंध में, सी ++ एक बड़े अंतर से जीतता है। हालांकि, इसे सबसे व्यापक ट्यूनिंग प्रयासों की भी आवश्यकता थी, जिनमें से कई परिष्कार के स्तर पर किए गए थे जो औसत प्रोग्रामर के लिए उपलब्ध नहीं होंगे।
[...] जावा संस्करण शायद लागू करने के लिए सबसे सरल था, लेकिन प्रदर्शन के लिए विश्लेषण करना सबसे कठिन था। विशेष रूप से कचरा संग्रह के आस-पास के प्रभाव जटिल थे और धुन के बहुत कठिन थे। "
सूत्रों का कहना है:
संपादित करें (2011-09-20)
"फेसबुक पर शब्द चल रहा है कि ' यथोचित लिखा सी ++ कोड बस तेजी से चलता है, ' जो PHP और जावा कोड को अनुकूलित करने में खर्च किए गए भारी प्रयास को रेखांकित करता है। विरोधाभासी रूप से, सी ++ कोड अन्य भाषाओं की तुलना में लिखना अधिक कठिन है, लेकिन कुशल कोड एक है। बहुत आसान [C ++ में लिखने के लिए अन्य भाषाओं की तुलना में]। "
- हर्ब Sutter पर // निर्माण / के हवाले से आंद्रेई Alexandrescu
सूत्रों का कहना है: