c# - सी#से सी++ कितनी तेजी से है?




c++ performance (18)

या अब यह दूसरी तरफ है?

मैंने जो सुना है उससे कुछ ऐसे क्षेत्र हैं जिनमें सी # सी ++ से तेज साबित होता है, लेकिन मुझे कभी भी इसका परीक्षण करने की हिम्मत नहीं हुई है।

सोचा था कि आप में से कोई भी इन अंतरों को विस्तार से समझा सकता है या इस पर जानकारी के लिए मुझे सही जगह पर इंगित कर सकता है।


'शर्मनाक समानांतर' समस्याओं के लिए, सी ++ पर इंटेल टीबीबी और ओपनएमपी का उपयोग करते समय मैंने सी # और टीपीएल के साथ किए गए समान (शुद्ध गणित) समस्याओं की तुलना में लगभग 10x प्रदर्शन वृद्धि देखी है। सिम एक ऐसा क्षेत्र है जहां सी # प्रतिस्पर्धा नहीं कर सकता है, लेकिन मुझे यह भी इंप्रेशन मिला कि टीपीएल का आकार काफी ऊंचा है।

उस ने कहा, मैं प्रदर्शन-महत्वपूर्ण कार्यों के लिए केवल सी ++ का उपयोग करता हूं, जहां मुझे पता है कि मैं बहुसंख्यक और परिणाम जल्दी प्राप्त कर पाऊंगा। बाकी सब कुछ के लिए, सी # (और कभी-कभी एफ #) ठीक है।


.NET भाषाएं सी ++ कोड जितनी तेजी से हो सकती हैं, या यहां तक ​​कि तेज़ी से भी हो सकती हैं, लेकिन सी ++ कोड में अधिक स्थिर थ्रूपुट होगा क्योंकि .NET रनटाइम को GC लिए रोकना होगा, भले ही यह इसके विरामों के बारे में बहुत चालाक हो।

इसलिए यदि आपके पास कुछ कोड है जो किसी भी विराम के बिना लगातार दौड़ना है, तो .NET कुछ समय पर विलंबता पेश करेगा, भले ही आप रनटाइम जीसी से बहुत सावधान रहें।


एक विशेष परिदृश्य जहां सी ++ में अभी भी ऊपरी हाथ है (और आने वाले वर्षों के लिए) तब होता है जब संकलन समय पर पॉलिमॉर्फिक निर्णय पूर्व निर्धारित किए जा सकते हैं।

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

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

ऐसे मामलों में (और स्वीकार्य रूप से, वे अक्सर विशेष समस्या डोमेन तक सीमित होते हैं), सी ++ सी # और तुलनीय भाषाओं के खिलाफ जीतता है।


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


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

इसलिए कई मामलों में सी ++ तेज है। लेकिन यह जवाब का केवल एक हिस्सा है। जिन मामलों में सी ++ वास्तव में तेज़ है, वे बेहद अनुकूलित प्रोग्राम हैं, जहां विशेषज्ञ प्रोग्रामर कोड के बाहर नरक को पूरी तरह से अनुकूलित करते हैं। यह न केवल बहुत समय लेने वाला (और इस प्रकार महंगा) है, बल्कि अधिक अनुकूलन के कारण आमतौर पर त्रुटियों की ओर जाता है।

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

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

ध्यान रखें कि एक सही प्रोग्राम को अनुकूलित करना अपेक्षाकृत आसान है, लेकिन एक अनुकूलित प्रोग्राम को सही करने के लिए बहुत कठिन है।

गति फायदे के वास्तविक प्रतिशत देना असंभव है, यह काफी हद तक आपके कोड पर निर्भर करता है। कई मामलों में, प्रोग्रामिंग भाषा कार्यान्वयन भी बाधा नहीं है। संदेहों का एक बड़ा सौदा के साथ http://benchmarksgame.alioth.debian.org/ पर बेंचमार्क लें, क्योंकि ये बड़े पैमाने पर अंकगणितीय कोड का परीक्षण करते हैं, जो आपके कोड के समान नहीं है।


ग्राफिक्स के लिए सी / सी ++ के माध्यम से जीडीआई की तुलना में मानक सी # ग्राफिक्स क्लास धीमा है। मुझे पता है कि इस भाषा के साथ कुछ भी नहीं है, कुल .NET प्लेटफ़ॉर्म के साथ, लेकिन ग्राफिक्स को डेवलपर को जीडीआई प्रतिस्थापन के रूप में पेश किया जाता है, और इसका प्रदर्शन इतना खराब है कि मैं ग्राफिक्स करने की भी हिम्मत नहीं करता इसके साथ।

हमारे पास एक साधारण बेंचमार्क है जिसका उपयोग हम यह देखने के लिए करते हैं कि ग्राफिक्स लाइब्रेरी कितनी तेज़ है, और यह बस खिड़की में यादृच्छिक रेखाएं खींच रही है। सी ++ / जीडीआई अभी भी 10000 लाइनों से घिरा हुआ है जबकि सी # / ग्राफिक्स को रीयल-टाइम में 1000 करने में कठिनाई है।


मैं इस प्रश्न के स्वीकार्य (और अच्छी तरह से उभरा) के जवाब के साथ असहमत से शुरू करने जा रहा हूं:

वास्तव में बहुत सारे कारण हैं कि JITted कोड उचित ढंग से अनुकूलित C ++ (या रनटाइम ओवरहेड के बिना अन्य भाषा) प्रोग्राम से धीमा गति से चलाएगा जिसमें निम्न शामिल हैं:

  • रनटाइम पर जेआईटीटिंग कोड पर खर्च किए गए गणना चक्र प्रोग्राम निष्पादन में उपयोग के लिए अनुपलब्ध हैं।

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

  • एक रन-टाइम ऑप्टिमाइज़र का समय बजट एक संकलन-समय अनुकूलक की तुलना में अधिक बाध्य होता है (जैसा कि एक अन्य टिप्पणीकर्ता ने बताया)

निचली पंक्ति: आखिरकार, आप निश्चित रूप से सी #+ में सी #+ में तेजी से कार्यान्वयन करने में सक्षम होंगे

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

यह एक बहुत लंबा और जटिल विषय है, लेकिन मुझे लगता है कि पूर्णता के लिए उल्लेख करना उचित है कि सी # के रनटाइम ऑप्टिमाइज़र उत्कृष्ट हैं, और रनटाइम पर कुछ गतिशील अनुकूलन करने में सक्षम हैं जो सी ++ के लिए संकलित समय के साथ उपलब्ध नहीं हैं ( स्थिर) अनुकूलक। इसके साथ ही, लाभ अभी भी मूल आवेदन की अदालत में गहराई से है, लेकिन गतिशील अनुकूलक ऊपर दिए गए " लगभग निश्चित रूप से" योग्यता का कारण है।

-

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

उन बेंचमार्क के साथ समस्या का एक बड़ा हिस्सा यह है कि आप सी ++ कोड नहीं लिख सकते हैं जैसे कि आप सी # लिख रहे थे और प्रतिनिधि परिणाम प्राप्त करने की उम्मीद करते हैं (उदाहरण के लिए। सी ++ में हजारों मेमोरी आवंटन करने से आपको भयानक संख्या मिल जाएगी।)

इसके बजाए, मैंने थोड़ा अधिक मूर्खतापूर्ण सी ++ कोड लिखा और सी # कोड @ वायरी प्रदान किए गए। सी ++ कोड में किए गए दो बड़े बदलाव थे:

1) प्रयुक्त वेक्टर :: आरक्षित ()

2) बेहतर कैश इलाके (संगत ब्लॉक) प्राप्त करने के लिए 2 डी सरणी को 1 डी तक चपटा

सी # (.NET 4.6.1)

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);
}

रन टाइम (रिलीज): इनिट: 124 एमएमएस, भरें: 165 एमएमएस

सी ++ 14 (क्लैंग v3.8 / सी 2)

#include <iostream>
#include <vector>

auto TestSuite::ColMajorArray()
{
    constexpr size_t ROWS = 5000;
    constexpr size_t COLS = 9000;

    auto initStart = std::chrono::steady_clock::now();

    auto arr = std::vector<double>();
    arr.reserve(ROWS * COLS);

    auto initFinish = std::chrono::steady_clock::now();
    auto initTime = std::chrono::duration_cast<std::chrono::microseconds>(initFinish - initStart);

    auto fillStart = std::chrono::steady_clock::now();

    for(auto i = 0, r = 0; r < ROWS; ++r)
    {
        for (auto c = 0; c < COLS; ++c)
        {
            arr[i++] = static_cast<double>(r * c);
        }
    }

    auto fillFinish = std::chrono::steady_clock::now();
    auto fillTime = std::chrono::duration_cast<std::chrono::milliseconds>(fillFinish - fillStart);

    return std::make_pair(initTime, fillTime);
}

रन टाइम (रिलीज): इनिट: 3 9 8μs (हाँ, यह माइक्रोसॉन्ड है), भरें: 152 एमएमएस

कुल रन टाइम: सी #: 28 9एमएस, सी ++ 152 एमएमएस (लगभग 9 0% तेज)

टिप्पणियों

  • उसी 1 डी सरणी कार्यान्वयन में सी # कार्यान्वयन को बदलना इनिट: 40ms, भरें: 171ms, कुल: 211ms ( सी ++ अभी भी लगभग 40% तेज था )।

  • किसी भी भाषा में "नियमित" कोड लिखने के बजाय सी ++ में "तेज़" कोड को डिज़ाइन और लिखना बहुत मुश्किल है।

  • यह (शायद) सी ++ में खराब प्रदर्शन पाने के लिए आश्चर्यजनक रूप से आसान है; हमने देखा कि अनारक्षित वैक्टर प्रदर्शन के साथ। और इस तरह के कई नुकसान हैं।

  • जब आप रनटाइम पर चल रहे सभी पर विचार करते हैं तो सी # का प्रदर्शन अद्भुत होता है। और वह प्रदर्शन अपेक्षाकृत आसान है।

  • सी ++ और सी # के प्रदर्शन की तुलना में अधिक अनावश्यक डेटा: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore

निचली पंक्ति यह है कि सी ++ आपको प्रदर्शन पर अधिक नियंत्रण देता है। क्या आप एक सूचक का उपयोग करना चाहते हैं? संदर्भ? स्मृति ढेर? ढेर? गतिशील बहुरूपता या स्थैतिक बहुरूपता (टेम्पलेट्स / सीआरटीपी के माध्यम से) के साथ एक vtable के रनटाइम ओवरहेड को खत्म? सी ++ में आपको ... er, इन सभी विकल्पों को (और अधिक) अपने आप को आदर्श रूप से प्राप्त करना होगा, आदर्श रूप से आपका समाधान उस समस्या को सबसे अच्छी तरह से संबोधित करता है जिसका आप सामना कर रहे हैं।

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


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


वास्तविक वास्तविक उत्तरों के बिना यह बेहद अस्पष्ट सवाल है।

उदाहरण के लिए; मैं बजाय 3 डी-गेम्स खेलता हूं जो सी #+ में सी #+ की तुलना में बनाए जाते हैं, क्योंकि प्रदर्शन निश्चित रूप से बहुत बेहतर होता है। (और मुझे एक्सएनए पता है, आदि, लेकिन असली चीज़ के पास यह कोई रास्ता नहीं आता है)।

दूसरी ओर, जैसा कि पहले उल्लेख किया गया है; आपको ऐसी भाषा में विकसित होना चाहिए जो आपको तेज़ी से करने की सुविधा देता है, और फिर यदि आवश्यक हो तो अनुकूलित करें।


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

मुझे संदेह है कि यह .NET या किसी भी जेआरई द्वारा किया जाता है, लेकिन जब मैं विश्वविद्यालय में था, तब इसकी समीक्षा की जा रही थी, इसलिए यह सोचने के लिए अनुचित नहीं है कि इस तरह की चीजें जल्द ही असली दुनिया में अपना रास्ता तलाश सकती हैं ।


सी ++ (या उस मामले के लिए सी) आपको अपने डेटा संरचनाओं पर बढ़िया नियंत्रण प्रदान करता है। यदि आप थोड़ा विकल्प चाहते हैं तो आपके पास वह विकल्प है। बड़े प्रबंधित जावा या .NET ऐप्स (ओडब्लूबी, Visual Studio 2005 ) जो जावा / .NET पुस्तकालयों की आंतरिक डेटा संरचनाओं का उपयोग करते हैं, उनके साथ सामान लेते हैं। मैंने ओबीबी डिजाइनर सत्रों को 400 एमबी रैम और क्यूब या ETL डिज़ाइन के लिए 100 एमबी के साथ-साथ बीआईडीएस का उपयोग करके देखा है।

एक अनुमानित वर्कलोड पर (जैसे कि अधिकतर मानक जो कई बार प्रक्रिया को दोहराते हैं) एक जेआईटी आपको कोड प्राप्त कर सकता है जिसे अनुकूलित किया गया है कि इसमें कोई व्यावहारिक अंतर नहीं है।

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


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

सी / सी ++ के बोनस सबसे अधिक स्पष्ट होते हैं यदि आप पॉइंटर्स के साथ सीधे चिपके रहते हैं और बूस्ट, std::vector और अन्य उच्च स्तरीय कंटेनर से बचते हैं, साथ ही साथ प्रत्येक छोटे फ़ंक्शन को inline करते हैं। जब भी संभव हो पुराने स्कूल एरे का प्रयोग करें। हां, आपको जावा या सी # में किए गए वही काम को पूरा करने के लिए कोड की अधिक पंक्तियों की आवश्यकता होगी क्योंकि आप उच्च स्तरीय कंटेनर से बचते हैं। यदि आपको गतिशील रूप से आकार की सरणी की आवश्यकता है, तो आपको बस अपने new T[] को इसी delete[] कथन (या std::unique_ptr उपयोग करें) के साथ std::unique_ptr - अतिरिक्त गति के लिए कीमत यह है कि आपको अधिक ध्यान से कोड करना होगा । लेकिन बदले में, आप अपने आप को प्रबंधित मेमोरी / कचरा कलेक्टर के ऊपरी हिस्से से छुटकारा पा सकते हैं, जो आसानी से जावा और .NET दोनों में भारी ऑब्जेक्ट-उन्मुख प्रोग्रामों के निष्पादन समय का 20% या अधिक हो सकता है, साथ ही साथ उन बड़े प्रबंधित मेमोरी सरणी अनुक्रमण लागत। कुछ विशिष्ट मामलों में सी ++ ऐप्स कुछ निफ्टी कंपाइलर स्विच से भी लाभ उठा सकते हैं।

मैं सी, सी ++, जावा, और सी # में एक विशेषज्ञ प्रोग्रामर हूं। मैंने हाल ही में 3 भाषाओं में सटीक उसी एल्गोरिदमिक प्रोग्राम को लागू करने के लिए दुर्लभ अवसर दिया था। कार्यक्रम में बहुत सारे गणित और बहु-आयामी सरणी संचालन थे। मैंने इसे सभी 3 भाषाओं में अत्यधिक अनुकूलित किया। परिणाम सामान्य रूप से कम कठोर तुलना में सामान्य रूप से देखते थे: जावा सी # से लगभग 1.3x तेज था (अधिकांश जेवीएम सीएलआर से अधिक अनुकूलित होते हैं), और सी ++ कच्चा सूचक संस्करण सी # से 2.1x तेज में आया था। ध्यान दें कि सी # प्रोग्राम केवल सुरक्षित कोड का उपयोग करता है- यह मेरी राय है कि आप unsafe कीवर्ड का उपयोग करने से पहले इसे C ++ में भी कोड कर सकते हैं।

अगर किसी को लगता है कि मेरे पास सी # के खिलाफ कुछ है, तो मैं कहकर बंद कर दूंगा कि सी # शायद मेरी पसंदीदा भाषा है। यह अब तक का सबसे तार्किक, सहज ज्ञान युक्त और तेज़ विकास भाषा है। मैं सी # में अपना प्रोटोटाइप करता हूं। सी # भाषा में जावा पर बहुत छोटे, सूक्ष्म फायदे हैं (हां, मुझे पता है कि माइक्रोसॉफ्ट को गेम में देर से और तर्कसंगत रूप से जावा की प्रतिलिपि बनाकर जावा की कई कमियों को ठीक करने का मौका मिला था)। जावा के Calendar वर्ग में टोस्ट किसी को भी? यदि माइक्रोसॉफ्ट ने कभी भी सीएलआर और .NET JITter को अनुकूलित करने के लिए वास्तविक प्रयास किया है, तो सी # गंभीरता से खत्म हो सकता है। मैं ईमानदारी से हैरान हूं कि वे पहले से नहीं हैं-उन्होंने सी # भाषा में इतनी सारी चीज़ें की हैं, क्यों न कि भारी-मारने वाले संकलक अनुकूलन के साथ इसका पालन करें? शायद अगर हम सभी विनती करते हैं।


हमेशा के रूप में, यह आवेदन पर निर्भर करता है। ऐसे मामले हैं जहां सी # शायद लापरवाही से धीमी है, और अन्य मामले जहां सी ++ 5 या 10 गुना तेज है, खासकर उन मामलों में जहां संचालन आसानी से सिम किया जा सकता है।


> After all, the answers have to be somewhere, haven't they? :)

Umm, no.

As several replies noted, the question is under-specified in ways that invite questions in response, not answers. To take just one way:

And then which programs? Which machine? Which OS? Which data set?


I suppose there are applications written in C# running fast, as well as there are more C++ written apps running fast (well C++ just older... and take UNIX too...)
- the question indeed is - what is that thing, users and developers are complaining about ...
Well, IMHO, in case of C# we have very comfort UI, very nice hierarchy of libraries, and whole interface system of CLI. In case of C++ we have templates, ATL, COM, MFC and whole shebang of alreadyc written and running code like OpenGL, DirectX and so on... Developers complains of indeterminably risen GC calls in case of C# (means program runs fast, and in one second - bang! it's stuck).
To write code in C# very simple and fast (not to forget that also increase chance of errors. In case of C++, developers complains of memory leaks, - means crushes, calls between DLLs, as well as of "DLL hell" - problem with support and replacement libraries by newer ones...
I think more skill you'll have in the programming language, the more quality (and speed) will characterize your software.


Inspired by this, I did a quick test with 60 percent of common instruction needed in most of the programs.

Here's the C# code:

for (int i=0; i<1000; i++)
{
    StreamReader str = new StreamReader("file.csv");
    StreamWriter stw = new StreamWriter("examp.csv");
    string strL = "";
    while((strL = str.ReadLine()) != null)
    {
        ArrayList al = new ArrayList();
        string[] strline = strL.Split(',');
        al.AddRange(strline);
        foreach(string str1 in strline)
        {
            stw.Write(str1 + ",");
        }
        stw.Write("\n");
    }
    str.Close();
    stw.Close();
}

String array and arraylist are used purposely to include those instructions.

Here's the c++ code:

for (int i = 0; i<1000; i++)
{
    std::fstream file("file.csv", ios::in);
    if (!file.is_open())
    {
        std::cout << "File not found!\n";
        return 1;
    }

    ofstream myfile;
    myfile.open ("example.txt");
    std::string csvLine;

    while (std::getline(file, csvLine))
    {
        std::istringstream csvStream(csvLine);
        std::vector csvColumn;
        std::string csvElement;

        while( std::getline(csvStream, csvElement, ‘,’) )
        {
            csvColumn.push_back(csvElement);
        }

        for (std::vector::iterator j = csvColumn.begin(); j != csvColumn.end(); ++j)
        {
            myfile << *j << ", ";
        }

        csvColumn.clear();
        csvElement.clear();
        csvLine.clear();
        myfile << "\n";
    }
    myfile.close();
    file.close();
}

The input file size I used was 40 KB.

And here's the result -

  • C++ code ran in 9 seconds.
  • C# code: 4 seconds!!!

Oh, but this was on Linux... With C# running on Mono ... And C++ with g++.

OK, this is what I got on Windows – Visual Studio 2003 :

  • C# code ran in 9 seconds.
  • C++ code – horrible 370 seconds!!!

Well, it depends. If the byte-code is translated into machine-code (and not just JIT) (I mean if you execute the program) and if your program uses many allocations/deallocations it could be faster because the GC algorithm just need one pass (theoretically) through the whole memory once, but normal malloc/realloc/free C/C++ calls causes an overhead on every call (call-overhead, data-structure overhead, cache misses ;) ).

So it is theoretically possible (also for other GC languages).

I don't really see the extreme disadvantage of not to be able to use metaprogramming with C# for the most applications, because the most programmers don't use it anyway.

Another big advantage is that the SQL, like the LINQ "extension", provides opportunities for the compiler to optimize calls to databases (in other words, the compiler could compile the whole LINQ to one "blob" binary where the called functions are inlined or for your use optimized, but I'm speculating here).


मेरे अनुभव में (और मैंने दोनों भाषाओं के साथ बहुत काम किया है), सी ++ की तुलना में सी # के साथ मुख्य समस्या उच्च स्मृति खपत है, और मुझे इसे नियंत्रित करने का एक अच्छा तरीका नहीं मिला है। यह स्मृति खपत थी जो अंततः .NET सॉफ़्टवेयर को धीमा कर देगी।

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







benchmarking