оно берется с кэша! Мока!
using System;
using System.Diagnostics;
using System.Threading;
namespace speedTest
{
static class Program
{
public struct index
{
public int x, y, z;
};
static int Main()
{
int counter = 0;
int count_values = 512 * 128 * 512;
index[] ordered_values = new index[count_values];
index[] random_values = new index[count_values];
{
int x = 0, y = 0, z = 0;
Random r = new Random();
for (int i = 0; i < count_values; ++i)
{
ordered_values[i].x = z;
ordered_values[i].y = y;
ordered_values[i].z = x;
x++;
if (x > 511)
{
x = 0;
y++;
}
if (y > 127)
{
y = 0;
z++;
}
random_values[i].x = r.Next(511);
random_values[i].y = r.Next(127);
random_values[i].z = r.Next(511);
}
}
Stopwatch timer = new Stopwatch();
Thread.Sleep(100);
{ // Multidimensional
long elapsedAllocation, elapsedFill, elapsedGet, number;
timer.Restart();
int[, ,] map = new int[512, 128, 512];
elapsedAllocation = timer.ElapsedTicks;
Console.WriteLine("Multidimensional allocate: {0}ms", Math.Round(elapsedAllocation * 1000f / Stopwatch.Frequency, 3));
timer.Restart();
for (int i = 0; i < 20; i++)
{
for (int x = 0; x < 512; x++)
{
for (int y = 0; y < 128; y++)
{
for (int z = 0; z < 512; z++)
{
++counter;
map[x, y, z] = counter;
}
}
}
}
elapsedFill = timer.ElapsedTicks;
Console.WriteLine("Multidimensional fill: {0}ms", Math.Round((elapsedFill / 20f) * 1000f / Stopwatch.Frequency, 3));
timer.Restart();
for (int i = 0; i < count_values; ++i)
{
number = map[ordered_values[i].x, ordered_values[i].y, ordered_values[i].z];
}
elapsedGet = timer.ElapsedTicks;
Console.WriteLine("Multidimensional get all times (ordered): {0}ms", Math.Round(elapsedGet * 1000f / Stopwatch.Frequency, 3));
timer.Restart();
for (int i = 0; i < count_values; ++i)
{
number = map[random_values[i].x, random_values[i].y, random_values[i].z];
}
elapsedGet = timer.ElapsedTicks;
Console.WriteLine("Multidimensional get all times (random): {0}ms", Math.Round(elapsedGet * 1000f / Stopwatch.Frequency, 3));
}
Thread.Sleep(100);
{ // Flattened
long elapsedAllocation, elapsedFill, elapsedGet, number;
timer.Restart();
int[] map = new int[512 * 128 * 512];
elapsedAllocation = timer.ElapsedTicks;
Console.WriteLine("Flattened allocate: {0}ms", Math.Round(elapsedAllocation * 1000f / Stopwatch.Frequency, 3));
timer.Restart();
for (int i = 0; i < 20; i++)
{
for (int x = 0; x < 512; x++)
{
for (int y = 0; y < 128; y++)
{
for (int z = 0; z < 512; z++)
{
++counter;
map[512 * 128 * x + 128 * y + z] = counter;
}
}
}
}
elapsedFill = timer.ElapsedTicks;
Console.WriteLine("Flattened fill: {0}ms", Math.Round((elapsedFill / 20f) * 1000f / Stopwatch.Frequency, 3));
timer.Restart();
for (int i = 0; i < count_values; ++i)
{
number = map[512 * 128 * ordered_values[i].x + 128 * ordered_values[i].y + ordered_values[i].z];
}
elapsedGet = timer.ElapsedTicks;
Console.WriteLine("Flattened get all times (ordered): {0}ms", Math.Round(elapsedGet * 1000f / Stopwatch.Frequency, 3));
timer.Restart();
for (int i = 0; i < count_values; ++i)
{
number = map[512 * 128 * random_values[i].x + 128 * random_values[i].y + random_values[i].z];
}
elapsedGet = timer.ElapsedTicks;
Console.WriteLine("Flattened get all times (random): {0}ms", Math.Round(elapsedGet * 1000f / Stopwatch.Frequency, 3));
}
Thread.Sleep(100);
{ // Jagged
long elapsedAllocation, elapsedFill, elapsedGet, number;
timer.Restart();
int[][][] map = new int[512][][];
for (int y = 0; y < 512; ++y)
{
map[y] = new int[128][];
for (int z = 0; z < 128; ++z)
{
map[y][z] = new int[512];
}
}
elapsedAllocation = timer.ElapsedTicks;
Console.WriteLine("Jagged allocate: {0}ms", Math.Round(elapsedAllocation * 1000f / Stopwatch.Frequency, 3));
timer.Restart();
for (int i = 0; i < 20; i++)
{
for (int x = 0; x < 512; x++)
{
for (int y = 0; y < 128; y++)
{
for (int z = 0; z < 512; z++)
{
++counter;
map[x][y][z] = counter;
}
}
}
}
elapsedFill = timer.ElapsedTicks;
Console.WriteLine("Jagged fill: {0}ms", Math.Round((elapsedFill / 20f) * 1000f / Stopwatch.Frequency, 3));
timer.Restart();
for (int i = 0; i < count_values; ++i)
{
number = map[ordered_values[i].x][ordered_values[i].y][ordered_values[i].z];
}
elapsedGet = timer.ElapsedTicks;
Console.WriteLine("Jagged get all times (ordered): {0}ms", Math.Round(elapsedGet * 1000f / Stopwatch.Frequency, 3));
timer.Restart();
for (int i = 0; i < count_values; ++i)
{
number = map[random_values[i].x][random_values[i].y][random_values[i].z];
}
elapsedGet = timer.ElapsedTicks;
Console.WriteLine("Jagged get all times (random): {0}ms", Math.Round(elapsedGet * 1000f / Stopwatch.Frequency, 3));
}
Console.Read();
return 0;
}
}
}
вот вариант с последовательнам и рандомным доступом:
MD
allocate 6
fill 198
get(order) 149
get(rand) 956
FLAT
allocate 0.21
fill 39
get(order) 62.5 \ ??WTF
get(rand) 59.58 / ??WTF
JAGGED
allocate 210
fill 52
get(order) 92
get(rand) 677