मैं इस प्रश्न का उत्तर स्वीकृत (और अच्छे से उत्कृष्ट) भाग से असहमत होकर शुरू करने जा रहा हूं:
वास्तव में बहुत सारे कारण हैं कि क्यों JITted कोड धीमे अनुकूलित C ++ (या रनटाइम ओवरहेड के बिना अन्य भाषा) प्रोग्राम की तुलना में धीमा चलेगा :
रनटाइम में JITting कोड पर खर्च की गई गणना चक्र, प्रोग्राम निष्पादन में उपयोग के लिए अनुपलब्ध है।
JITter में किसी भी गर्म रास्ते को सीपीयू में निर्देश और डेटा कैश के लिए आपके कोड के साथ प्रतिस्पर्धा करनी होगी। हम जानते हैं कि जब प्रदर्शन पर बात आती है तो कैश हावी होता है और सी ++ जैसी देशी भाषाओं में परिभाषा के अनुसार इस प्रकार का विवाद नहीं होता है।
एक रन-टाइम अनुकूलक के समय बजट जरूरी है बहुत अधिक की तुलना में विवश एक संकलन समय अनुकूलक के (के रूप में एक और टिप्पणीकार ने बताया)
नीचे पंक्ति: अंततः, आप लगभग निश्चित रूप से C # में एक तेज कार्यान्वयन बनाने में सक्षम होंगे , जितना आप C # में कर सकते हैं ।
अब, कहा गया है कि वास्तव में कितनी तेजी से मात्रात्मक नहीं है, क्योंकि बहुत अधिक चर हैं: कार्य, समस्या डोमेन, हार्डवेयर, कार्यान्वयन की गुणवत्ता और कई अन्य कारक। आपने प्रदर्शन के अंतर को निर्धारित करने के लिए अपने परिदृश्य पर परीक्षण चलाएंगे, और फिर यह तय करेंगे कि यह अतिरिक्त प्रयास और जटिलता के लायक है या नहीं।
यह एक बहुत लंबा और जटिल विषय है, लेकिन मुझे लगता है कि यह संपूर्णता के लिए ध्यान देने योग्य है कि C # का रनटाइम ऑप्टिमाइज़र उत्कृष्ट है, और रनटाइम के दौरान कुछ गतिशील अनुकूलन करने में सक्षम है जो केवल अपने संकलन-समय के साथ C ++ के लिए उपलब्ध नहीं हैं स्थिर) आशावादी। यहां तक कि इसके साथ, मूल आवेदन के न्यायालय में लाभ अभी भी गहराई से है, लेकिन डायनेमिक ऑप्टिमाइज़र " लगभग " का कारण है ऊपर दिए गए निश्चित रूप से" क्वालीफायर है।
-
सापेक्ष प्रदर्शन के संदर्भ में, मैं उन आंकड़ों और चर्चाओं से भी परेशान था, जिन्हें मैंने कुछ अन्य उत्तरों में देखा था, इसलिए मैंने सोचा कि मैं इसमें झंकार करूंगा और साथ ही, ऊपर दिए गए बयानों के लिए कुछ समर्थन प्रदान करूंगा।
उन बेंचमार्क के साथ समस्या का एक बड़ा हिस्सा यह है कि आप सी ++ कोड नहीं लिख सकते हैं जैसे कि आप सी # लिख रहे थे और परिणाम प्राप्त करने की उम्मीद करते हैं (उदाहरण: सी ++ में हजारों मेमोरी आवंटन प्रदर्शन कर रहे हैं जो आपको भयानक संख्या देने जा रहे हैं।)
इसके बजाय, मैंने थोड़ा और मुहावरेदार सी ++ कोड लिखा और सी # कोड के खिलाफ तुलना की। C ++ कोड में मैंने जो दो बड़े बदलाव किए थे, वे थे:
1) इस्तेमाल किया वेक्टर :: रिजर्व ()
2) बेहतर कैश इलाके (सन्निहित ब्लॉक) को प्राप्त करने के लिए 2d सरणी को 1d पर समतल कर दिया
C # (.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);
}
रन टाइम (रिलीज़): Init: 124ms, भरें: 165ms
C ++ 14 (Clang v3.8 / C2)
#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);
}
रन टाइम (रिलीज़): Init: 398 (s (हाँ, यह माइक्रोसेकंड है), भरें: 152ms
कुल रन समय: C #: 289ms, C ++ 152ms (लगभग 90% तेज)
टिप्पणियों
C # कार्यान्वयन को एक ही 1d सरणी कार्यान्वयन में बदलने से Init: 40ms, Fill: 171ms, कुल: 211ms ( C ++ अभी भी लगभग 40% तेज ) हो गया।
C ++ में "तेज" कोड को डिजाइन करना और लिखना बहुत कठिन है, क्योंकि यह किसी भी भाषा में "नियमित" कोड लिखना है।
यह (शायद) C ++ में खराब प्रदर्शन पाने के लिए आश्चर्यजनक रूप से आसान है; हमने देखा कि अनारक्षित वैक्टर प्रदर्शन के साथ। और इस तरह के बहुत सारे नुकसान हैं।
जब आप रनटाइम पर चल रहे होते हैं, उस पर विचार करने के दौरान C # का प्रदर्शन अद्भुत होता है। और यह प्रदर्शन तुलनात्मक रूप से आसान है।
C ++ और C # के प्रदर्शन की तुलना करने वाले अधिक महत्वपूर्ण आंकड़े: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore
लब्बोलुआब यह है कि C ++ आपको प्रदर्शन पर अधिक नियंत्रण देता है। क्या आप एक सूचक का उपयोग करना चाहते हैं? संदर्भ? स्टैक मेमोरी? ढेर? गतिशील बहुरूपता या स्थैतिक बहुरूपता (टेम्पलेट्स / CRTP के माध्यम से) के साथ एक व्यवहार्य के क्रम ओवरहेड को खत्म करना? C ++ में आपको ... एर, को प्राप्त करना है इन सभी विकल्पों (और अधिक) को स्वयं बनाने के , आदर्श रूप से ताकि आपका समाधान समस्या से निपटने के लिए सबसे अच्छा पता लगाए।
अपने आप से पूछें कि क्या आप वास्तव में चाहते हैं या उस नियंत्रण की आवश्यकता है, क्योंकि ऊपर दिए गए तुच्छ उदाहरण के लिए भी, आप देख सकते हैं कि हालांकि प्रदर्शन में एक महत्वपूर्ण सुधार है, इसे उपयोग करने के लिए एक गहन निवेश की आवश्यकता है।