2016-02-26 6 views
6

मैं उच्च प्रदर्शन सी ++ एप्लिकेशन को सी # में फिर से लिख रहा हूं। सी # ऐप सी ++ मूल से काफी धीमी है। प्रोफाइलिंग मुझे बताती है कि सी # ऐप सरणी तत्वों तक पहुंचने में अधिकतर समय बिताता है। इसलिए मैं एक सरल सरणी पहुंच बेंचमार्क बनाते हैं। मुझे others doing a similiar comparison से पूरी तरह से अलग परिणाम मिलते हैं।सी ++ सरणी बनाम सी # पीआरटी गति भ्रम

सी ++ कोड:

#include <limits> 
#include <stdio.h> 
#include <chrono> 
#include <iostream> 

using namespace std; 
using namespace std::chrono; 

int main(void) 
{ 
    high_resolution_clock::time_point t1 = high_resolution_clock::now(); 

    int xRepLen = 100 * 1000; 
    int xRepCount = 1000; 

    unsigned short * xArray = new unsigned short[xRepLen]; 
    for (int xIdx = 0; xIdx < xRepLen; xIdx++) 
     xArray[xIdx] = xIdx % USHRT_MAX; 

    int * xResults = new int[xRepLen]; 

    for (int xRepIdx = 0; xRepIdx < xRepCount; xRepIdx++) 
    { 

     // in each repetition, find the first value, that surpasses xArray[xIdx] + 25 - i.e. we will perform 25 searches 
     for (int xIdx = 0; xIdx < xRepLen; xIdx++) 
     { 
      unsigned short xValToBreach = (xArray[xIdx] + 25) % USHRT_MAX; 
      xResults[xIdx] = 0; 

      for (int xIdx2 = xIdx + 1; xIdx2 < xRepLen; xIdx2++) 
      if (xArray[xIdx2] >= xValToBreach) 
      { 
       xResults[xIdx] = xIdx2; break; 
      } 

      if (xResults[xIdx] == 0) 
       xResults[xIdx] = INT_MAX; 
     } 
    } 

    high_resolution_clock::time_point t2 = high_resolution_clock::now(); 
    auto duration = duration_cast<milliseconds>(t2 - t1).count(); 
    cout << "Elasped miliseconds " << duration; 
    getchar(); 
} 

सी # कोड:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 

namespace arrayBenchmarkCs 
{ 
    class Program 
    { 
     public static void benchCs() 
     { 
      unsafe 
      { 
       int xRepLen = 100 * 1000; 
       int xRepCount = 1000; 

       ushort[] xArr = new ushort[xRepLen]; 
       for (int xIdx = 0; xIdx < xRepLen; xIdx++) 
        xArr[xIdx] = (ushort)(xIdx % 0xffff); 

       int[] xResults = new int[xRepLen]; 

       Stopwatch xSw = new Stopwatch(); xSw.Start(); 
       fixed (ushort * xArrayStart = & xArr [0]) 
       { 
        for (int xRepIdx = 0; xRepIdx < xRepCount; xRepIdx++) 
        { 

         // in each repetition, go find the first value, that surpasses xArray[xIdx] + 25 - i.e. we will perform 25 searches 
         ushort * xArrayEnd = xArrayStart + xRepLen; 
         for (ushort* xPtr = xArrayStart; xPtr != xArrayEnd; xPtr++) 
         { 
          ushort xValToBreach = (ushort)((*xPtr + 25) % 0xffff); 
          int xResult = -1; 
          for (ushort * xPtr2 = xPtr + 1; xPtr2 != xArrayEnd; xPtr2++) 
           if (*xPtr2 >= xValToBreach) 
           { 
            xResult = (int)(xPtr2 - xArrayStart); 
            break; 
           } 

          if (xResult == -1) 
           xResult = int.MaxValue; 

          // save result 
          xResults[xPtr - xArrayStart] = xResult; 
         } 
        } 
       } // fixed 

       xSw.Stop(); 

       Console.WriteLine("Elapsed miliseconds: " + (xSw.ElapsedMilliseconds.ToString("0")); 
      } 
     } 

     static void Main(string[] args) 
     { 
      benchCs(); 
      Console.ReadKey(); 
     } 
    } 
} 

मेरे काम कंप्यूटर (i7-3770) पर, सी ++ संस्करण लगभग 2x तेजी से सी # संस्करण की तुलना में है। मेरे घर कंप्यूटर (i7-5820K) पर सी ++ सी # संस्करण की तुलना में 1.5x तेज है। दोनों रिलीज में मापा जाता है। मुझे उम्मीद थी कि सी # में पॉइंटर्स का उपयोग करके मैं सरणी सीमा जांच से बचूंगा और प्रदर्शन दोनों भाषाओं में समान होगा।

  • घर दूसरों सी # पा रहे हैं सी ++ के रूप में एक ही गति से होने के लिए आते हैं:

    तो मेरे सवालों का अनुसरण कर रहे हैं?

  • यदि पॉइंटर्स के माध्यम से नहीं है तो मैं सी ++ स्तर पर सी # प्रदर्शन कैसे प्राप्त कर सकता हूं?
  • विभिन्न कंप्यूटरों पर विभिन्न स्पीडअप का चालक क्या हो सकता है?

किसी भी संकेत बहुत सराहना की है, डैनियल

+0

मुझे आशा है कि आप डिबगर के बिना बेंचमार्क निष्पादित कर रहे हैं (विजुअल स्टूडियो में F5 के बजाय CTRL + F5) – xanatos

+0

@xanatos: हां। हालांकि शॉर्टकट के लिए धन्यवाद। –

+0

* ushort * xArrayEnd = xArrayStart + xRepLen; * आप इसे 'for' चक्र – xanatos

उत्तर

0

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

यदि आप unsafe पर जाने के इच्छुक हैं तो वास्तव में आपके सी ++ प्रदर्शन-महत्वपूर्ण सामग्री को मिश्रित-मोड असेंबली में कोड करने और आपके सी # गोंद कोड से कॉल करने से रोकने में कुछ भी नहीं है।

+0

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

+0

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

संबंधित मुद्दे