Предварительно выделить массивы в Matlab? - PullRequest
7 голосов
/ 02 июня 2011

Я использую простой цикл for, чтобы обрезать большое количество изображений и затем сохранить их в массиве ячеек. Я продолжаю получать сообщение:

Переменная croppedSag, кажется, изменяет размер на каждой итерации цикла. Рассмотрим предварительное распределение для скорости.

Я уже видел это несколько раз, когда кодировал в MATLAB. Я всегда игнорировал это, и мне любопытно, насколько предварительное распределение увеличит время выполнения, если у меня будет, скажем, 10 000 изображений или большее число?

Кроме того, я прочитал о предварительном распределении в документации, и там говорится, что для этой цели нужно использовать zeros(). Как бы я использовал это для кода ниже?

croppedSag = {};
for i = 1:sagNum
    croppedSag{end+1} = imcrop(SagArray{i},rect);
end

Я не совсем следовал примерам в документации.

1 Ответ

12 голосов
/ 02 июня 2011

Предварительное выделение массива всегда хорошая идея в Matlab. Альтернатива - иметь массив, который увеличивается во время каждой итерации в цикле. Каждый раз, когда элемент добавляется в конец массива, Matlab должен создать совершенно новый массив, скопировать содержимое старого массива в новый, а затем, наконец, добавить новый элемент в конец. Предварительное выделение устраняет необходимость выделять новый массив и тратить время на копирование существующего содержимого массива в новую память.

Тем не менее, в вашем случае вы можете не увидеть столько выгод, сколько ожидаете. При копировании массива ячеек в новый, увеличенный массив ячеек Matlab фактически не нужно копировать содержимое массива ячеек (данные изображения), а только указатели на , которые данные.

Тем не менее, нет никаких причин не делать предварительное распределение (если вы заранее не знаете окончательный размер). Вот предварительно выделенная версия вашего цикла:

croppedSag = cell(1, sagNum);
for ii = 1:sagNum
    croppedSag{ii} = imcrop(SagArray{ii}, rect);
end

Я также изменил индексную переменную "i" на "ii", чтобы она не перезаписывала мнимую единицу.

Вы также можете переписать этот цикл в одну строку, используя функцию cellfun:

croppedSag = cellfun(@(im) imcrop(im, rect), SagArray);

Вот запись в блоге, которая может быть информативной:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...