Я часто обнаруживал, что делаю что-то вроде этого:
unprocessedData = fetchData(); % returns a vector of structs or objects
processedData = []; % will be full of structs or objects
for dataIdx = 1 : length(unprocessedData)
processedDatum = process(unprocessedData(dataIdx));
processedData = [processedData; processedDatum];
end
Что, хотя и функционально, не оптимально - вектор processedData
растет внутри цикла. Даже mlint
предупреждает меня, что я должен рассмотреть возможность предварительного распределения скорости.
Если бы данные были вектором int8
, я мог бы сделать это:
% preallocate processed data array to prevent growth in loop
processedData = zeros(length(unprocessedData), 1, 'int8');
и измените цикл, чтобы заполнять векторные слоты, а не объединять.
существует ли способ предварительно выделить вектор, чтобы впоследствии он мог содержать структуры или объекты?
Обновление: вдохновлено Ответом Азима , я просто изменил порядок зацикливания. Обработка последнего элемента в первую очередь приводит к предварительному выделению всего вектора в первом обращении, поскольку отладчик подтверждает:
unprocessedData = fetchData();
% note that processedData isn't declared outside the loop - this breaks
% it if it'll later hold non-numeric data. Instead we exploit matlab's
% odd scope rules which mean that processedData will outlive the loop
% inside which it is first referenced:
for dataIdx = length(unprocessedData) : -1 : 1
processedData(dataIdx) = process(unprocessedData(dataIdx));
end
Это требует, чтобы любые объекты, возвращаемые process()
, имели действительный конструктор с нулевым аргументом , поскольку MATLAB инициализирует processedData
при первой записи в него с реальными объектами.
mlint
все еще жалуется на возможный рост массива, но я думаю, что это потому, что он не может распознать итерацию обратного цикла ...