Я часто делал что-то вроде этого:
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
по-прежнему жалуется на возможный рост массива, но я думаю, это потому, что он не может распознать итерацию обратного цикла ...