0

I am working on application that requires so many loops and array access to compare arrays. I implemented the same application in c++ and I noticed very big difference in performance please notice I used pointers instead of array index-based access in the c++ version. Then I tried to implement just a small part of my code in both c++ and C#. The C# code is listed below it takes av of 400 ms to execute when measured using stopwatch. Moreover when I increase the limit of the first for to say 10000 the program will never execute just like a deadlock.

            int[] A = new int[10000];
            int[] B = new int[10000];
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for(int i=0;i<100;i++)
                for(int j=0;j<i;j++)
                    for (int k = 0; k < 10000; k++)
                    {
                        A[k] = k;
                        B[k] = A[k] + j;
                    }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();

my question is how to improve this killing performance of arrays in c# ?

myPC is 4GB RAM core i5 2.2GHz

  • 1
    Have you tried running this in release mode? Also seems redundant to set the same 10k indices over and over. .. – Ron Beyer Jul 21 '15 at 22:38
  • Actually no, this is only part of my work – sisck vabrigas Jul 21 '15 at 22:39
  • same thing , my question is about array access optimization , not about speed – sisck vabrigas Jul 21 '15 at 22:49
  • It seems that 64 bit JIT compiler has a better optimization than 32bits. – Graffito Jul 21 '15 at 23:00
  • http://stackoverflow.com/questions/9304726/array-bounds-check-elimination-in-the-clr – Alexei Levenkov Jul 21 '15 at 23:03
  • @Graffito thats true on a 64 bit system running a 64 bit program. Compiling this for 32 bit and running on a 32 bit machine should show similar results, the issue comes with translating registers I think. – Ron Beyer Jul 21 '15 at 23:03
  • 2
    You do realize that increasing it to `10,000` on the outer loop means you're doing `1,000,100,000,000` array writes, and `500,050,000,000` array reads, right? That's not taking into account all the operations on your index variables, either. The problem is your benchmark, not array performance in C#. If the equivalent program you've written in C++ actually completes this, it means the compiler essentially removed half your code which it deemed redundant (the first two loops, for example). – Rob Jul 21 '15 at 23:55

3 Answers3

2

I don't think that accessing arrays is really an issue here. If I replace the inner part of your loop with just increasing a counter:

int count = 0;

for (int i = 0; i < 100; i++)
    for (int j = 0; j < i; j++)
        for (int k = 0; k < 10000; k++)
        {
            count++;
        }

the execution takes 88 ms on my machine, while your version takes 156 ms (this is in debug mode, in release without debugging it's about 2x faster). I'd say this is understandable since your code is performing 2 operations instead of 1 operation when only increasing the counter.

Keep in mind that your code enters the loop 4,950,000 times, which is a lot. If you increase your outer loop to 10000 repeats, you will be entering the loop 499,950,000,000 times.

If I were you, I would look into optimizing your algorithm like the other answer suggests. If that is not possible, you should at least have this code execute on a background thread with a progress indicator (and an option to cancel, if possible) for the user.

vesan
  • 3,289
  • 22
  • 35
0

A. Run this in release mode

B. Make sure you hand-optimize, your code is functionally equivalent to:

for (int k = 0; k < 10000; k++)
{
    A[k] = k;
    B[k] = A[k] + 99;
}
Ron Beyer
  • 11,003
  • 1
  • 19
  • 37
  • you are missing the point , the problem is not with code writing, its more focused on optimizing array access when the access is required for too many times – sisck vabrigas Jul 21 '15 at 22:51
  • You can use pointers in C# similar to how they are with C++, however it requires pinning and the initial overhead for fast-access items like arrays may give little benefit for the effort. BTW, your code doesn't deadlock, the application is not responding to the windows message pump because its busy, and windows remembers how long its not responding for and marks it as not responding. See https://msdn.microsoft.com/en-us/library/28k1s2k6.aspx for info on pointers in C# – Ron Beyer Jul 21 '15 at 22:54
0

Like "versan" said, you are doing a lot of operations so it's normal that it takes a lot of time to complete.

I worked with both C# and C++, the only difference that you may have with a code like this is the optimizations done by the compiler (JIT vs GCC) and the fact that the GC can interrupts your C# program to do the garbage collection stuff.

Array access in C# are basically the same as using pointers in C++

MSE
  • 327
  • 3
  • 8