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