d2: разница между выделением массива через new и назначением литерала массива
Рассмотрим следующий код:
class C {
immutable(double[][]) data;
this() {
immutable(double[])[] blocks = [];
immutable(double)[] block;
foreach (x; 0 .. 5) {
block = [];
block ~= 0.1 * x;
block ~= 1.0 * x;
block ~= 10.0 * x;
blocks ~= block;
}
this.data = blocks;
}
}
Это упрощенный "сухой экстракт" моего кода, который заполняет массив массивов значениями. Этот фрагмент кода работает, как и ожидалось, но поскольку я новичок в D, Я не уверен, что делаю это правильно.
Действительно ли назначение литерала массива выделяет память правильным образом или лучше использовать что-то вроде new double[0]
? Разве нет некоторых оговорок при переназначении одного и того же литерала?
2 ответа:
Присвоение пустому литералу имеет тот же эффект, что и присвоение нулю. Он не выделяет никакой памяти. Выделение происходит, когда вы объединяетесь в "блок". Это приводит к перераспределению массива три раза, я думаю, что если значения статически известны, то он может быть оптимизирован дальше. В любом случае, я бы, вероятно, предварительно выделил "блок" с 3 элементами только один раз, затем назначил соответствующие элементы каждой итерации и конкат в "блоки" (он будет выполнять копию здесь). Я ожидаю, что вы не знаете ... значение" x " статично. Если вы это сделаете, вы также можете статически инициализировать емкость для "блоков".
Назначение
[]
ничего не выделяет. Это то же самое, что назначитьnull
или вообще не инициализировать динамический массив. Это делает его таким, что массив имеетlength
из0
иptr
, который являетсяnull
. Только когда свойство массиваptr
ненулевое, он имеет какую-либо выделенную ему память.В таком виде вы можете просто переместить объявление
block
в строку, где вы назначаете его[]
, и избавиться от назначения. Как бы то ни было, вы напрасно повторно используете переменная снова и снова. Поскольку он используется только в цикле, это единственное место, где он должен существовать.Если вы хотите уменьшить вероятность дополнительных перераспределений массива при добавлении к нему, то либо используйте
reserve
илиstd.array.appender
.Вы действительно должны прочитать эту статью или массивы в D. Это должно помочь вам понять, как работают массивы в D.