C ++ array vs C # ptr speed offset

I am rewriting a high performance C ++ application in C #. A C # application is noticeably slower than the original C ++. Profiling tells me that a C # application spends more time accessing array elements. Therefore, I am creating a simple array access test. I get completely different results than others that make a similar comparison .

C ++ Code:

#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 - ie 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(); } 

C # code:

 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 - ie 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(); } } } 

On my working computer (i7-3770), the C ++ version is about 2x faster than the C # version. On my home computer (i7-5820K), C ++ is 1.5 times faster than the C # version. Both are measured in Release. I was hoping that using pointers to C # I would avoid checking the boundaries of the array, and the performance would be the same in both languages.

So my questions are:

  • home come others find that c # has the same speed as c ++?
  • How can I get C # performance to C ++ level, if not through pointers?
  • What can be a driver of different accelerations on different computers?

Any hint is much appreciated, Daniel

+6
source share
1 answer

You won’t get such a hardcore number that crunches to C ++ speed. Using pointer arithmetic and unsafe code leads you to be a little there (it's almost twice as slow if you remove unsafe and fixed parts). C # is not compiled into native code, and the code that it runs is filled with additional checks, etc.

If you want to go unsafe , then there really is nothing that would prevent you from coding your critical C ++ stuff in a mixed-mode assembly and calling it from your C # code.

0
source

All Articles