Speed of Regular Arrays vs Jagged Arrays vs Accessing Arrays with Poiters vs Arrays on Stack 

 

The good side of pointers: speed !!! – see thee numbers below

The bed sides of pointers: less readeable code, no range control, unsafe code cannot span multiply threads, in rare cases possible faster running out of memory as garbage collector cannot move fixed data  

 

The fastest: one-dimentional arrays on stack (about 15-20% faster than one-dimensional arrays accessed with pointers).

 

   

        int d3 = 400, d4 = 85;

        string msg = "";

 

       void Arr3D()

        {

            Regular3();  //3.55 sec.

            Jagged3();  //2.03 sec.

            Pointers3();   //2.04 sec.

            Pointers3Optimized();  //1.25 sec.

            Pointers3HighlyOptimized();   //0.61 sec.

         }

 

       void Arr4D()

        {

            Regular4();  //3.14 sec.

            Jagged4();  //1.89 sec.

            Pointers4();  //1.86 sec.

            Pointers4Optimized ();  //1.11 sec.

            Pointers4HighlyOptimized ();  //0.67 sec.

        }

 

 

 

        void Regular3()

        {

           

            int di=d3, dj=d3, dk=d3;

            int[, ,] A1 = new int[di, dj, dk];

            int[, ,] A2 = new int[di, dj, dk];

 

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            sw.Start();

            for (int i = 0; i < di; i++)

                  for (int j = 0; j < dj; j++)

                        for (int k = 0; k < dk; k++)                           

                            {

                                A1[i, j, k] = i;

                                A2[i, j, k] = A1[i, j, k];

                            }

                            

 

            sw.Stop();

            msg += sw.Elapsed.ToString() + "\r\n";

        }

 

 

 

 

        void Jagged3()

        {

         

            int di = d3, dj = d3, dk = d3;

            int[][][] A1 = new int[di][][];

            int[][][] A2 = new int[di][][];

            for (int i = 0; i < di; i++)

            {

                A1[i] = new int[dj][];

                A2[i] = new int[dj][];

                for (int j = 0; j < dj; j++)

                {

                    A1[i][j] = new int[dk];

                    A2[i][j] = new int[dk];                   

                }

            }

 

           

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            sw.Start();

            for (int i = 0; i < di; i++)

                for (int j = 0; j < dj; j++)

                    for (int k = 0; k < dk; k++)                      

                        {

                            A1[i][j][k] = i;

                            A2[i][j][k] = A1[i][j][k];

                        }                         

 

            sw.Stop();

            msg += sw.Elapsed.ToString() + "\r\n";

        }

 

 

 

 

        void Pointers3()

        {

          

            int di = d3, dj = d3, dk = d3;

            int[, ,] A1 = new int[di, dj, dk];

            int[, ,] A2 = new int[di, dj, dk];

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

 

            unsafe

            {

                fixed (int* p1 = &A1[0, 0, 0], p2 = &A2[0, 0, 0])

                {                   

                    sw.Start();

                    for (int i = 0; i < di; i++)

                        for (int j = 0; j < dj; j++)

                            for (int k = 0; k < dk; k++)                           

                                {

                                    *(p1 + i * dj * dk  + j * dk + k) = i;

                                    *(p2 + i * dj * dk  + j * dk  + k) = *(p1 + i * dj * dk + j * dk+ k);

                                }

 

             

                    sw.Stop();

                }

            }

            msg += sw.Elapsed.ToString() + "\r\n";

        }

 

 

 

        void Pointers3Optimized()

        {

          

            int di = d3, dj = d3, dk = d3;

            int[, ,] A1 = new int[di, dj, dk];

            int[, ,] A2 = new int[di, dj, dk];

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            int d1, d2;

            unsafe

            {

                fixed (int* p1 = &A1[0, 0, 0], p2 = &A2[0, 0, 0])

                {

                    sw.Start();

                    for (int i = 0; i < di; i++)

                    {

                        d1 = i * dj * dk;

                        for (int j = 0; j < dj; j++)

                        {

                            d2 = j * dk;

                            for (int k = 0; k < dk; k++)

                            {                              

                                    *(p1 + d1 + d2 + k) = i;

                                    *(p2 + d1 + d2 + k) = *(p1 + d1+ d2 + k);                                

                            }

                        }

                    }

 

 

                    sw.Stop();

                }

            }

            msg += sw.Elapsed.ToString() + "\r\n";

        }

 

 

        void Pointers3HighlyOptimized()

        {

          

            int di = d3, dj = d3, dk = d3, kk;

            int[, ,] A1 = new int[di, dj, dk];

            int[, ,] A2 = new int[di, dj, dk];

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            int d1, d2, djdk = dj * dk;

            unsafe

            {

                fixed (int* p1 = &A1[0, 0, 0], p2 = &A2[0, 0, 0])

                {

                    sw.Start();

                  

                    for (int i = 0; i < di; i++)

                    {

                        d1 = i * djdk;

                        for (int j = 0; j < dj; j++)

                        {

                            d2 = d1 + j * dk;

                            for (int k = 0; k < dk; k++)

                            {

                                   kk = d2 + k;

  *(p1 + kk) = i;

                                    *(p2 + kk) = *(p1 + kk);                              

                            }

                        }

                    }

 

 

                    sw.Stop();

                }

            }

            textBox1.Text += sw.Elapsed.ToString() + "\r\n";

        }

 

      

 

 

       

 

        void Regular4()

        {

           

            int di = d4, dj = d4, dk = d4, dm = d4;

            int[, , ,] A1 = new int[di, dj, dk, dm];

            int[, , ,] A2 = new int[di, dj, dk, dm];

 

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            sw.Start();

            for (int i = 0; i < di; i++)

                for (int j = 0; j < dj; j++)

                    for (int k = 0; k < dk; k++)

                        for (int m = 0; m < dm; m++)

                        {

                            A1[i, j, k, m] = i;

                            A2[i, j, k, m] = A1[i, j, k, m];

                        }

 

 

            sw.Stop();

            msg += sw.Elapsed.ToString() + "\r\n";

        }

 

 

 

 

        void Jagged4() 

        {

          

            int di = d4, dj = d4, dk = d4, dm = d4;

            int[][][][] A1 = new int[di][][][];

            int[][][][] A2 = new int[di][][][];

            for (int i = 0; i < di; i++)

            {

                A1[i] = new int[dj][][];

                A2[i] = new int[dj][][];

                for (int j = 0; j < dj; j++)

                {

                    A1[i][j] = new int[dk][];

                    A2[i][j] = new int[dk][];

                    for (int k = 0; k < dk; k++)

                    {

                        A1[i][j][k] = new int[dm];

                        A2[i][j][k] = new int[dm];

                    }

                }

            }

 

 

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            sw.Start();

            for (int i = 0; i < di; i++)

                for (int j = 0; j < dj; j++)

                    for (int k = 0; k < dk; k++)

                        for (int m = 0; m < dm; m++)

                        {

                            A1[i][j][k][m] = i;

                            A2[i][j][k][m] = A1[i][j][k][m];

                        }

 

            sw.Stop();

            msg += sw.Elapsed.ToString() + "\r\n";

        }

 

 

 

 

        void Pointers4()

        {

           

            int di = d4, dj = d4, dk = d4, dm = d4;

            int[, , ,] A1 = new int[di, dj, dk, dm];

            int[, , ,] A2 = new int[di, dj, dk, dm];

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

 

            unsafe

            {

                fixed (int* p1 = &A1[0, 0, 0, 0], p2 = &A2[0, 0, 0, 0])

                {

                    sw.Start();

                    for (int i = 0; i < di; i++)

                        for (int j = 0; j < dj; j++)

                            for (int k = 0; k < dk; k++)

                                for (int m = 0; m < dm; m++)

                                {

                                    *(p1 + i * dj * dk * dm + j * dk * dm + k * dm + m) = i;

                                    *(p2 + i * dj * dk * dm + j * dk * dm + k * dm + m) = *(p1 + i * dj * dk * dm + j * dk * dm + k * dm + m);

                                }

 

 

                    sw.Stop();

                }

            }

            msg += sw.Elapsed.ToString() + "\r\n";

        }

 

 

 

        void Pointers4Optimized()

        {

           

            int di = d4, dj = d4, dk = d4, dm = d4;

            int[, , ,] A1 = new int[di, dj, dk, dm];

            int[, , ,] A2 = new int[di, dj, dk, dm];

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            int d1, d2, d3;

            unsafe

            {

                fixed (int* p1 = &A1[0, 0, 0, 0], p2 = &A2[0, 0, 0, 0])

                {

                    sw.Start();

                    for (int i = 0; i < di; i++)

                    {

                        d1 = i * dj * dk * dm;

                        for (int j = 0; j < dj; j++)

                        {

                            d2 = j * dk * dm;

                            for (int k = 0; k < dk; k++)

                            {

                                d3 = k * dm;

                                for (int m = 0; m < dm; m++)

                                {

                                    *(p1 + d1 + d2 + d3 + m) = i;

                                    *(p2 + d1 + d2 + d3 + m) = *(p1 + d1 + d2 + d3 + m);

                                }

                            }

                        }

                    }

 

 

                    sw.Stop();

                }

            }

            msg += sw.Elapsed.ToString() + "\r\n";

        }

 

 

        void Pointers4HighlyOptimized()

        {

           

            int di = d4, dj = d4, dk = d4, dm = d4, kk;

            int[, , ,] A1 = new int[di, dj, dk, dm];

            int[, , ,] A2 = new int[di, dj, dk, dm];

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            int d1, d2, d3, djdkdm = dj * dk * dm, dkdm = dk * dm;

            unsafe

            {

                fixed (int* p1 = &A1[0, 0, 0, 0], p2 = &A2[0, 0, 0, 0])

                {

                    sw.Start();

 

                    for (int i = 0; i < di; i++)

                    {

                        d1 = i * djdkdm;

                        for (int j = 0; j < dj; j++)

                        {

                            d2 = d1 + j * dkdm;

                            for (int k = 0; k < dk; k++)

                            {

                                d3 = d2 + k * dm;

                                for (int m = 0; m < dm; m++)

                                {

                                    kk = d3 + m;

  *(p1 + kk) = i;

                                    *(p2 + kk) = *(p1 + kk);

                                }

                            }

                        }

                    }

 

 

                    sw.Stop();

                }

            }

            msg += sw.Elapsed.ToString() + "\r\n";

        }

 

 

 

 

        private void ArrysOnStack()

        {

 

 

            unsafe

            {

 

                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

                int size = 30000;

                int* A = stackalloc int[size];

                int* B = stackalloc int[size];

 

                sw.Start();

                for (int i = 0; i < size; i++)

                {

                    *(A + i) = 1;

                    for (int j = 1; j < size; j++)

                    {

                        *(B + i) = *(A + i);

                    }

                }

                sw.Stop();

                msg = sw.Elapsed.ToString() + "  " +   B[5].ToString() + "\r\n";

 

              

                int[] A2 = new int[size];

                int[] B2 = new int[size];

 

                sw.Reset();

                sw.Start();

 

                fixed(int* a = &A2[0], b= &B2[0])

                {

                for (int i = 0; i < size; i++)

                {

                    *(a + i) = 1;

                    for (int j = 1; j < size; j++)

                    {

                        *(b + i) = *(a + i);

                    }

                }

                }

                sw.Stop();

                msg += sw.Elapsed.ToString() + "  " + B[5].ToString();

            }

        }