为啥 Matlab 警告我“不推荐预分配”

Posted

技术标签:

【中文标题】为啥 Matlab 警告我“不推荐预分配”【英文标题】:Why is Matlab warning me that "preallocation not recommended"为什么 Matlab 警告我“不推荐预分配” 【发布时间】:2017-06-21 21:03:48 【问题描述】:

当我在 Matlab 中遇到警告时,我正在为 Andrew Ng 的 Coursera 机器学习课程编写一个函数。我还没有写出答案应该是什么,但起始代码都在这里,除了一行用于解释目的。问题不是寻找问题的答案,而是对 Matlab 警告的解释。

我得到的警告(不是错误)说:

Line 6: The variable 'g' appears to be preallocated but preallocation is not recommended here 

这是代码

function g = sigmoid(z)
%SIGMOID Compute sigmoid function
%   g = SIGMOID(z) computes the sigmoid of z.

% You need to return the following variables correctly 
g = zeros(size(z));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the sigmoid of each value of z (z can be a matrix,
%               vector or scalar).

g = 1./z;

% =============================================================

end

【问题讨论】:

预分配在分配数组的单个元素时很有用。当您一次替换整个数组时不会。 【参考方案1】:

这在 The MathWorks 的 a blog post by Loren Shure 中有所介绍,特别是在“常见的误解”部分。一小段摘录:

用户经常被告知要预分配,以至于我们有时会看到在代码中预分配了变量,即使它是不必要的。这不仅使代码复杂化,而且实际上可能导致预分配旨在缓解的问题,即运行时性能和峰值内存使用量。

将您的情况与 Loren 给出的示例进行比较,您使用 zeros 函数预先分配 g,然后使用 1./z 的结果重新分配它。对zeros 的调用分配的内存在评估1./z 时会被丢弃。这样做的效果是需要两倍于所需的内存,一块用于预分配的零,另一块用于1./z 的结果。

简而言之,在这种情况下,请相信Code Analyzer。

【讨论】:

那么g(:) = 1./z; 呢?那应该行得通。假设gz 是巨大的变量,那么在这种情况下预分配是否有用? @thewaywewalk:在示例代码中使用g(:) = 1./z;删除代码分析器的警告和突出显示,它可能避免冗余内存分配,但我怀疑在这种情况下预分配会给你带来什么。充其量,我认为这将是洗礼:没有缺点,但也没有真正的优势。 g(:) 的作用与 g 本身有什么不同? @heretoinfinity:colon operator 用于赋值时,将使用右侧的内容以线性(即按列)索引顺序填充 g。它本质上将g 视为一维矩阵,因此g1./z 只需具有相同的元素总数,但可以具有不同的大小或维度数。【参考方案2】:

线

g = zeros(size(z));

是多余的,因为在它之后你将g重新定义为

g = 1./z;

【讨论】:

以上是关于为啥 Matlab 警告我“不推荐预分配”的主要内容,如果未能解决你的问题,请参考以下文章

Matlab/Mex:mxarray.h 中的转换警告

Matlab:抑制uiputfile的警告对话框

在 MATLAB 中使用回归函数时出现排名不足警告

Matlab中带有函数名称的变量的警告

为啥 FxCop 给我一个“DoNotCastUnnecessarily”警告?

为啥我的编译器警告只有一个被禁止?