.
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений (для 6,863 пользователей)
|
Что-то я не смог избавиться от "оптимизаций компилятором", которые ухудшили результат получения данных при ordered и random индексах..
UPD: получилось.
Intel Pentium 4 3.00 Ghz
UPD2:
Вот такие результаты:
array size: 512 * 128 * 512 = 33554432
--- Multidimensional
allocate: 25.945ms
fill: 8221.827ms
get Ordered: 6834.768ms
get Random Order: 10833.646ms
--- Flattened
allocate: 39.469ms
fill: 985.824ms
get Ordered: 5357.747ms
get Random Order: 2922.386ms
--- Jagged
allocate: 3119.915ms
fill: 328.575ms
get Ordered: 6037.242ms
get Random Order: 8589.737ms
И вот такие результаты на более малого размера объём:
array size: 256 * 64 * 256 = 4194304
--- Multidimensional
allocate: 2.107ms
fill: 99.551ms
get Ordered: 96.638ms
get Random Order: 401.702ms
--- Flattened
allocate: 0.201ms
fill: 50.118ms
get Ordered: 49.65ms
get Random Order: 281.263ms
--- Jagged
allocate: 39.366ms
fill: 39.935ms
get Ordered: 50.619ms
get Random Order: 390.059ms
Заметьте, что в более малого объёма, как раз есть оптимизация на основе сортировки, а в большом нету..
Это случаем не потому что там идёт какое-то разбиение участка памяти на куски из-за слишком больших размеров?
Вот код обновил:
using System; using System.Diagnostics; using System.Threading;
namespace speedTest { static class Program { public struct index { public int x, y, z; };
static int Main() { long elapsed, number; int width = 256; int height = 64; int depth = 256; int volume = width * height * depth;
Console.WriteLine("array size: {0} * {1} * {2} = {3}", width, height, depth, volume);
index[] indicesOrdered = new index[volume]; index[] indicesRandom = new index[volume];
{ // fill up get values Random rnd = new Random(); int i = 0;
for (int z = 0; z < depth; ++z) { for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { indicesOrdered[i].x = z; indicesOrdered[i].y = y; indicesOrdered[i].z = x;
indicesRandom[i].x = rnd.Next(width); indicesRandom[i].y = rnd.Next(height); indicesRandom[i].z = rnd.Next(depth);
++i; } } } }
Stopwatch timer = new Stopwatch();
Console.WriteLine(" --- Multidimensional"); Thread.Sleep(100);
{ // Multidimensional int counter = 0;
timer.Restart();
int[,,] map = new int[width, height, depth];
elapsed = timer.ElapsedTicks; Console.WriteLine("allocate: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); timer.Restart();
for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < depth; z++) { ++counter; map[x, y, z] = counter; } } }
elapsed = timer.ElapsedTicks; Console.WriteLine("fill: \t\t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); timer.Restart();
for (int i = 0; i < volume; ++i) { number = map[indicesOrdered[i].x, indicesOrdered[i].y, indicesOrdered[i].z]; }
elapsed = timer.ElapsedTicks; Console.WriteLine("get Ordered: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); timer.Restart();
for (int i = 0; i < volume; ++i) { number = map[indicesRandom[i].x, indicesRandom[i].y, indicesRandom[i].z]; }
elapsed = timer.ElapsedTicks; Console.WriteLine("get Random Order: \t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); }
Console.WriteLine(" --- Flattened"); Thread.Sleep(100);
{ // Flattened int counter = 0;
timer.Restart();
int[] map = new int[width * height * depth];
elapsed = timer.ElapsedTicks; Console.WriteLine("allocate: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); timer.Restart();
for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < depth; z++) { ++counter; map[width * height * x + height * y + z] = counter; } } }
elapsed = timer.ElapsedTicks; Console.WriteLine("fill: \t\t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); timer.Restart();
for (int i = 0; i < volume; ++i) { number = map[width * height * indicesOrdered[i].x + height * indicesOrdered[i].y + indicesOrdered[i].z]; }
elapsed = timer.ElapsedTicks; Console.WriteLine("get Ordered: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); timer.Restart();
for (int i = 0; i < volume; ++i) { number = map[width * height * indicesRandom[i].x + height * indicesRandom[i].y + indicesRandom[i].z]; }
elapsed = timer.ElapsedTicks; Console.WriteLine("get Random Order: \t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); }
Console.WriteLine(" --- Jagged"); Thread.Sleep(100);
{ // Jagged int counter = 0;
timer.Restart();
int[][][] map = new int[width][][]; for (int y = 0; y < width; ++y) { map[y] = new int[height][];
for (int z = 0; z < height; ++z) { map[y][z] = new int[depth]; } }
elapsed = timer.ElapsedTicks; Console.WriteLine("allocate: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); timer.Restart();
for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < depth; z++) { ++counter; map[x][y][z] = counter; } } }
elapsed = timer.ElapsedTicks; Console.WriteLine("fill: \t\t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); timer.Restart();
for (int i = 0; i < volume; ++i) { number = map[indicesOrdered[i].x][indicesOrdered[i].y][indicesOrdered[i].z]; }
elapsed = timer.ElapsedTicks; Console.WriteLine("get Ordered: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); timer.Restart();
for (int i = 0; i < volume; ++i) { number = map[indicesRandom[i].x][indicesRandom[i].y][indicesRandom[i].z]; }
elapsed = timer.ElapsedTicks; Console.WriteLine("get Random Order: \t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3)); } Console.Read(); return 0; } } }
|