我经常发现自己做类似这样的事情:
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');
将循环修改为填充向量插槽而不是连接。
有没有一种方法可以预分配向量,以便随后可以容纳结构或对象?
更新:受Azim的答案启发,我只是颠倒了循环顺序。首先处理最后一个元素会在第一次命中时强制对整个向量进行预分配,调试器确认如下:
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
仍然会发出可能的数组增长的警告,但我认为这是因为它无法识别反向循环迭代...