我使用一个简单的for循环来裁剪大量图像,然后将它们存储在单元格数组中.我一直收到消息:
变量
croppedSag似乎在每次循环迭代时改变大小.考虑预先分配速度.
我在MATLAB编写代码之前已经多次看过这个.我总是忽略它,并且好奇有多少预先分配将增加运行时间,如果我有10,000个图像或更大的数字?
另外,我已阅读有关在文档中预分配的内容,并说它zeros()可用于此目的.我如何将其用于下面的代码?
croppedSag = {};
for i = 1:sagNum
croppedSag{end+1} = imcrop(SagArray{i},rect);
end
Run Code Online (Sandbox Code Playgroud)
我没有完全按照文档中的示例进行操作.
array1 = 5*rand(496736,1);
array2 = 25*rand(9286,1);
output = zeros(numel(array1), numel(array2)); % Requires 34GB RAM
output = zeros(numel(array1), numel(array2),'logical'); % Requires 4.3GB RAM
output = abs(bsxfun(@minus, array1.', array2)) <= 2; % Requires 34GB RAM
output = pdist2(array1(:), array2(:)) <= 2; % Requires 34GB RAM
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。包含496736 * 9286个double值的数组应为34GB,而包含相同数量元素的逻辑数组仅需要4.3GB(小8倍)。后两种情况会发生这种情况,因为它们使用的中间矩阵包含双精度的所有距离对,需要完整的34GB,而逻辑矩阵直接作为逻辑直接预分配,并且需要4.3GB。
令人惊讶的部分是:
output = abs(array1.' - array2); % Requires 34GB RAM
output = abs(array1.' - array2) <= 2; % Requires 4.3GB RAM ?!?
Run Code Online (Sandbox Code Playgroud)
什么?!?为什么由于中间双矩阵的创建,隐式扩展不要求相同的34GB RAM output = abs(array1.' - array2)? …
我经常发现自己在做这样的事情:
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
Run Code Online (Sandbox Code Playgroud)
尽管功能强大,但并不是最佳选择- processedData向量在循环内增长。甚至mlint警告我,我应该考虑预先分配速度。
如果数据是的向量int8,我可以这样做:
% preallocate processed data array to prevent growth in loop
processedData = zeros(length(unprocessedData), 1, 'int8');
Run Code Online (Sandbox Code Playgroud)
并修改循环以填充向量插槽,而不是连接起来。
有没有一种方法可以预分配向量,以便随后可以容纳结构或对象?
更新:受Azim的回答启发,我只是颠倒了循环顺序。首先处理最后一个元素将在第一次命中时强制整个向量进行预分配,因为调试器确认:
unprocessedData = fetchData();
% note that processedData isn't declared outside the loop - this …Run Code Online (Sandbox Code Playgroud) 我实现了有限差分算法来求解偏微分方程。
网格是大小为 [Nx, Nz] 的结构化二维域,已求解 Nt 次。
我预先分配包含所有解决方案的对象:
sol = zeros(Nx, Nz, Nt, 'single') ;
Run Code Online (Sandbox Code Playgroud)
这很容易变得太大,并且我收到“内存不足”错误。不幸的sparse是不适用于 N 维数组。
对于这个问题来说,知道这些值并不重要,不言而喻,随着网格间距的减小和模拟时间的增加,RAM 使用量呈指数增长。
我知道我不需要为了改进解决方案而存储每个时刻。只需存储前两个时间步就足够了。然而,出于后处理的原因,我需要在所有时间步长(或至少是总数的约数)访问解决方案。这可能有助于指定,即使在解决方案之后,网格仍然主要由零填充。
我是在打一场失败的战斗还是有更有效的方法来继续(其他类型的对象,矢量化......)?
谢谢。
我想初始化一个包含一些数据的数组。我创建了一个随机矩阵(使用np.empty),然后将其乘以np.nan。有什么问题吗?或者我应该坚持更好的做法吗?
进一步解释我的情况:我有需要存储在数组中的数据。假设我有 8 行数据。每行的元素数不相等,所以我的矩阵行长度需要和最长的行一样长。在其他行中,某些元素将不会被填充。我不想使用零,因为我的一些数据实际上可能是零。
我意识到我可以使用一些我知道我的数据永远不会使用的值,但 nans 绝对更清晰。只是想知道这是否会导致以后的处理出现任何问题。我意识到我需要使用nanmax代替max等等。
我在 Rust 结构中有一个实现,它构建了一个非常大的字符串,最终将写入文件。我想知道是否可以通过确保字符串变量具有适当的容量来加快速度,但它并没有按照我预期的方式工作。
这就是我所做的:
let sum = izip!(self.ts, self.x, self.y).fold(String::with_capacity(capacity), |acc, x| {
format!("{}{}, {}, {}\n", acc, x.0, x.1, x.2)
});
Run Code Online (Sandbox Code Playgroud)
我认为该字符串将累积到第一个参数中,因此我用必要的容量实例化了它。然而,通过检查从 ( ) 输出的字符串的容量sum,我可以发现我的假设是错误的。
有人可以帮助我理解我的理解fold是错误的吗?也许可以给出一个关于构建这个字符串的更好方法的提示?