Speed of Regular Arrays vs Jagged Arrays vs Accessing Arrays with Poiters vs Arrays on Stack vs Range Operators vs
Vector Operators.
public
class Program
{
    static void Main(string[] args) =>
BenchmarkRunner.Run<Test1>();
}
[MemoryDiagnoser]
public
class Test1
{
    int N = 32000;
    int[] X;
    public Test1()
    {
        X = new int[N];
        for (int i = 0; i < N; i++)
            X[i] = i;
    }
        
    [Benchmark]
    public void fLINQ()
    {
        int[] Y1 = X.Skip(N / 2).Take(N /
4).ToArray();
    }
        
    [Benchmark]
    public void fFor()
    {
        int[] Y2 = new int[N / 4];
        int j = 0;
        for (int i = N / 2; i < 3 * N / 4;
i++)
            Y2[j++] = X[i];
    }
        
    [Benchmark]
    public void fRange()
    {
        int[] Y3 = X[(N / 2)..(3 * N / 4)];
    }
        
    [Benchmark]
    public void tVector()
    {
        int[] Y = new int[N / 4];
        int j = 0;
        for (int i = N / 2; i < 3 * N / 4; i
+= Vector<int>.Count)
        {
            Vector<int> vector = new
Vector<int>(X, i);
            vector.CopyTo(Y, j);
            j += Vector<int>.Count;
        }
    }
}
        
        
|
Method  | Mean      | Error     | StdDev   
| Gen0   | Allocated |
|--------
|----------:|----------:|----------:|-------:|----------:|
|
fLINQ   | 17.100 us | 0.1577 us | 0.1475 us | 3.8147
|  31.37 KB |
|
fFor    | 
6.202 us | 0.0650 us | 0.0608 us | 3.8147 |  31.27 KB |
|
fRange  | 
1.579 us | 0.0226 us | 0.0189 us | 3.8166 |  31.27 KB |
|
fVector |  2.342 us | 0.0233 us | 0.0206
us | 3.8147 |  31.27 KB |
    
        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();
           
}
       
}