И на счет быстродействия пару замечаний:
— на фоне скорости чтения/записи памяти математические операции для процессора это раз плюнуть. Даже sin/cos вычисляются за почти за пару тактов.
— время доступа для кэшей процессора register/L1/L2/… для каждого следующего уровня отличается на порядок: 1 такт/10 тактов/100 тактов/1000 тактов. Поэтому не факт что использование предвычисленных данных будет давать значительный прирост, возможно даже и наоборот (но это не точно, практика — критерий истины).
До меня как до жирафа доходило что у вас многомерный случай, и используемая библиотека оптимизирована именно под это. Уверен что для 2D/3D/4D моя функция «уделает» hilbert_i2c() в тестах (не хотите проверить?), но:
— под бОльшие мерности пространства оптимизации меняются
— мой трехмерный мозг туго работает с N-мерностями выше трех (это усложняет визуальную отладку)
Ну возьмем для примера 3D.
Значит в наивной реализации 32 прохода по циклу. А в оптимизированном варианте можно сделать, скажем, за 4 прохода, правда нужен индекс порядка 64Mb размером.
Можно конечно и по диагонали. А можно и по окто-дереву. Кривая замыкается в кольцо и начало можно назначать произвольно. Если взять начало в середине получатся те же свойства что и у кривой Гилберта. Кстати, функцию get_GCurve_XY можно еще примерно в два раза ускорить.
private const d : int = 4;
private const dm : int = (1 << d) - 1;
private var xx_ : int;
private var yy_ : int;
public function get_GCurve_XY(i: int) : void
{
var j : int;
var v : int;
var b : int;
var f : int;
xx_ = yy_ = b = 0;
f = i;
for (j = d - 1; j >= 0; --j)
{
f += (1 << (j << 1)) >> 1;
v = ((f >> (j << 1)) + b) & 3;
b = v ^ 2;
v ^= b >> 1;
xx_ |= (v & 1) << j;
yy_ |= (v >> 1) << j;
}
}
//.............................................................................
public function DP_Curve() : void
{
var px : int;
var py : int;
var x : int;
var y : int;
var i : int;
var nn : int = (1 << (d << 1));
for (i = 0; i < nn; ++i)
{
get_GCurve_XY(i);
if (0 != i)
draw_Line(px, py, xx_, yy_);
px = xx_;
py = yy_;
}
}
— на фоне скорости чтения/записи памяти математические операции для процессора это раз плюнуть. Даже sin/cos вычисляются за почти за пару тактов.
— время доступа для кэшей процессора register/L1/L2/… для каждого следующего уровня отличается на порядок: 1 такт/10 тактов/100 тактов/1000 тактов. Поэтому не факт что использование предвычисленных данных будет давать значительный прирост, возможно даже и наоборот (но это не точно, практика — критерий истины).
— под бОльшие мерности пространства оптимизации меняются
— мой трехмерный мозг туго работает с N-мерностями выше трех (это усложняет визуальную отладку)
Значит в наивной реализации 32 прохода по циклу. А в оптимизированном варианте можно сделать, скажем, за 4 прохода, правда нужен индекс порядка 64Mb размером.
Причем если использовать массив заранее рассчитанных значений (до любой выбранной глубины) то количество итераций в цикле можно серьезно уменьшить.
Кстати, для Z-order функция выглядит так: