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.