d2: разница между размещением массива через new и назначением литерала массива - PullRequest
2 голосов
/ 28 марта 2012

Рассмотрим следующий код:

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 ]

1 голос
/ 28 марта 2012

Назначение [] ничего не выделяет.Это то же самое, что присваивать null или вообще не инициализировать динамический массив.Это делает так, чтобы массив имел length из 0 и ptr, что равно null.Только когда свойство ptr массива ненулевое, у него есть память, выделенная ему.

В таком виде вы можете просто переместить объявление block в строку, гдеВы назначаете это [] и избавляетесь от назначения.В существующем состоянии вы без необходимости повторно используете переменную снова и снова.Так как он используется только внутри цикла, это единственное место, где он должен существовать.

Если вы хотите уменьшить вероятность наличия дополнительных перераспределений массива при добавлении к нему, тогда либо используйте reserve или std.array.appender.

Вы действительно должны прочитать эту статью или массивы в D. Это должно вам очень помочь с вашимпонимание того, как работают массивы в D.

1 голос
/ 28 марта 2012

Назначение пустого литерала имеет тот же эффект, что и присвоение нулю. Он не выделяет никакой памяти. Распределение происходит, когда вы объединяетесь в «блок». Это приводит к перераспределению массива три раза, я думаю, что если значения статически известны, его можно оптимизировать дальше. В любом случае, я бы, вероятно, предварительно выделил «блок» с 3-мя элементами только один раз, затем назначил бы соответствующие элементы на каждой итерации и объединил бы в «блоки» (здесь будет выполнено копирование). Я ожидаю, что вы не знаете значение «х» статически. Если вы это сделаете, вы также можете статически инициализировать емкость для «блоков».

...