在 Matlab 中预分配数组?
我正在使用一个简单的 for
循环来裁剪大量图像,然后将它们存储在一个元胞数组中.我不断收到消息:
I am using a simple for
loop to crop a large amount of images and then storing them in a cell array. I keep getting the message:
变量 croppedSag
似乎在每次循环迭代中都会改变大小.考虑为速度进行预分配.
The variable
croppedSag
appears to change size on every loop iteration. Consider preallocating for speed.
我之前在 MATLAB 中编码时已经多次看到这种情况.我一直忽略它,并且很好奇如果我有 10,000 个图像或更多图像,预分配会增加多少运行时间?
I have seen this several times before while coding in MATLAB. I have always ignored it and am curious how much preallocating will increase the runtime if I have, say, 10,000 images or a larger number?
另外,我在文档中阅读了关于预分配的内容,它说要为此使用 zeros()
.我将如何将其用于下面的代码?
Also, I have read about preallocating in the documentation and it says to use zeros()
for that purpose. How would I use that for the code below?
croppedSag = {};
for i = 1:sagNum
croppedSag{end+1} = imcrop(SagArray{i},rect);
end
我没有完全遵循文档中的示例.
I didn't quite follow the examples in the documentation.
在 Matlab 中预先分配数组总是一个好主意.另一种方法是让数组在每次迭代期间通过循环增长.每次在数组末尾添加一个元素,Matlab 都必须生成一个全新的数组,将旧数组的内容复制到新数组中,最后在末尾添加新元素.预分配消除了分配新数组和花时间将数组现有内容复制到新内存中的需要.
Pre-allocating an array is always a good idea in Matlab. The alternative is to have an array which grows during each iteration through a loop. Each time an element is added to the end of the array, Matlab must produce a totally new array, copy the contents of the old array into the new one, and then, finally, add the new element at the end. Pre-allocating eliminates the need to allocate a new array and spend time copying the existing contents of the array into the new memory.
但是,就您而言,您可能不会看到预期的那么多好处.当将元胞数组复制到一个新的、扩大的元胞数组时,Matlab 实际上并不需要复制元胞数组的内容(图像数据),而只是指向 那个数据.
However, in your case, you might not see as much benefit as you might expect. When copying the cell array to a new, enlarged cell array, Matlab doesn't actually have to copy the contents of the cell array (the image data), but only pointers to that data.
尽管如此,没有理由不预先分配(除非您实际上事先不知道最终大小).这是循环的预分配版本:
Nonetheless, there is no reason not to pre-allocate (unless you actually don't know the final size in advance). Here's a pre-allocated version of your loop:
croppedSag = cell(1, sagNum);
for ii = 1:sagNum
croppedSag{ii} = imcrop(SagArray{ii}, rect);
end
我还将索引变量i"更改为ii",以免覆盖虚数单位.
I also changed the index variable "i" to "ii" so that it doesn't over-write the imaginary unit.
您也可以使用 cellfun 函数在一行中重写此循环:
You can also re-write this loop in one line using the cellfun function:
croppedSag = cellfun(@(im) imcrop(im, rect), SagArray);
这是一个可能提供信息的博客条目:
Here's a blog entry that might be informative: