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 элементами только один раз, затем назначил бы соответствующие элементы на каждой итерации и объединил бы в "блоки" (здесь будет выполнено копирование). Я ожидаю, что вы не знаете значение "х" статически. Если вы это сделаете, вы также можете статически инициализировать емкость для "блоков".
Назначение []
ничего не выделяет Это так же, как назначение null
или не инициализировать динамический массив вообще. Это делает так, чтобы массив имел length
из 0
а также ptr
который null
, Это только когда массив ptr
свойство ненулевое, что у него есть память, которая ему выделена.
В таком виде вы можете просто двигаться block
объявление в строке, где вы его назначаете []
и избавиться от задания. В существующем состоянии вы без необходимости повторно используете переменную снова и снова. Поскольку он используется только внутри цикла, это единственное место, где он должен существовать.
Если вы хотите уменьшить вероятность дополнительных перераспределений массива при добавлении к нему, то либо используйте reserve
или же std.array.appender
,
Вы действительно должны прочитать эту статью или массивы в D. Это должно помочь вам в понимании того, как работают массивы в D.