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.

Другие вопросы по тегам