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