У меня есть кубический 3D-массив "класс", например:
function Array3D(size) {
this.data = new Array(size*size*size);
var makeIndex = function(p) {
return p[0] + p[1]*size + p[2]*size*size;
}
this.get = function(p) { return this.data[makeIndex(p)]; };
this.set = function(p, value) { this.data[makeIndex(p)] = value; };
}
Я хотел бы обобщить несколько измерений, но без ущерба для производительности доступа. Вот мой простой подход:
function ArrayND(size, N) {
var s = 1;
for(var i = 0; i < N; i++) s *= size;
this.data = new Array(s);
var makeIndex = function(p) {
var ind = 0;
for(var i = N-1; i >= 0; i--)
ind = ind*size + p[i];
return ind;
}
this.get = function(p) { return this.data[makeIndex(p)]; };
this.set = function(p, value) { this.data[makeIndex(p)] = value; };
}
Есть ли способ «развернуть» мою функцию makeIndex
, чтобы цикл оценивался один раз во время объявления, но не при вызове? Не сведут ли накладные расходы использование сгенерированного во время выполнения кода из eval
или new Function()
преимущество отсутствия циклов?
И size
, и N
по сути являются константами, поэтому повторяющееся умножение и итерация кажутся чем-то, что можно сделать только один раз.
ind += p[i] * Math.pow( size, i );
, в результате чего получаетсяp[0] + p[i] * size + p[1] * size * size + ...
? - person Šime Vidas   schedule 02.12.2012[0, size, size*size, size*size*size, ...]
. Умножение этого массива на массивp
и добавление его в сумму должно выполняться при каждой операции получения/установки. - person Šime Vidas   schedule 02.12.2012size
является константой, длинаp
является константой, поэтому в принципе цикл можно развернуть. - person Eric   schedule 02.12.2012N
значений, превышающих 3. Цикл выполняетN
умножения иN
сложения, тогда как развернутое выражение выполняетN-1
сложения, ноN*(N-1)/2
умножения. Например, дляN=10
цикл выполняет 10 умножений, тогда как развернутое выражение выполняет 45 умножений. Так что, я бы сказал, придерживайтесь цикла. - person Šime Vidas   schedule 03.12.2012