初始化或预分配的最佳实践 - MATLAB

时间:2014-11-06 20:05:37

标签: performance matlab

我的问题并不是明确依赖于一段代码,而是更具概念性。

与某些编程语言不同,MATLAB并不要求变量在使用之前进行明确初始化。例如,在脚本文件中途定义' myVector'这是完全有效的:

myVector = vectorA .* vectorB

我的问题是:将变量(例如上面的' myVector')初始化为零然后为它们赋值,或者在整个程序中保持初始化是否更快?

这里直接比较了我所谈论的内容:

全程初始化:

varA = 8;
varB = 2;

varC = varA - varB;
varD = varC * varB;

在开始时初始化:

varA = 8;
varB = 2;
varC = 0;
varD = 0;

varC = varA - varB;
varD = varC * varB;

一方面,无缘无故地拥有这些额外的代码行似乎有点浪费。但另一方面,有一点意义是,一次为程序分配所有内存而不是在运行时分散会更快。

有没有人有一点见解?

2 个答案:

答案 0 :(得分:5)

Initializing at start:代码复制并粘贴到MATLAB编辑器窗口中,您会收到如下警告 -

enter image description here

如果你进入Details,你会读到这个 ​​-

Explanation 
The code does not appear to use the assignment to the indicated variable. This situation occurs when any of the following are true:
Another assignment overwrites the value of the variable before an operation uses it.
The specified argument value contains a typographical error, causing it to appear unused.
The code does not use all values returned by a function call...

在我们的案例中,此警告的原因是The code does not use all values。因此,这澄清了初始化/预分配对这种情况没有帮助。


我们什么时候应该预先分配?

根据我的经验,预分配有助于您以后需要将索引编入其中的一部分。

因此,如果您需要索引varC的一部分来存储结果,预分配将有所帮助。因此,这会更有意义 -

varC = zeros(...)
varD = zeros(...)
varC(k,:) = varA - varB;
varD(k,:) = varC * varB;

同样,在索引时,如果超出varC的大小,MATLAB会花时间尝试为它分配更多的内存空间,这样会慢一点。因此,将输出变量预先分配到您认为用于存储结果的 maximum size 。但是,如果你不知道结果的大小,你就会陷入困境并且必须将结果附加到输出变量中,这肯定会减慢速度。

答案 1 :(得分:3)

好的!我做了一些测试,结果如下。

这是我用于“整个”变量赋值的代码:

tic;
a = 1;
b = 2;
c = 3;
d = 4;
e = a - b;
f = e + c;
g = f - a;
h = g * c;
i = h - g;
j = 9 * i;
k = [j i h];
l = any(k);
b2(numel(b2) + 1) = toc

以下是“At Start”变量赋值的代码:

tic;
a = 1;
b = 2;
c = 3;
d = 4;
e = 0;
f = 0;
g = 0;
h = 0;
i = 0;
j = 0;
k = 0;
l = 0;
e = a - b;
f = e + c;
g = f - a;
h = g * c;
i = h - g;
j = 9 * i;
k = [j i h];
l = any(k);
b1(numel(b1) + 1) = toc

我将时间保存在矢量'b1'和'b2'中。每个都只运行MATLAB和Chrome运行,是MATLAB中唯一的脚本文件。每次运行201次。因为第一次运行程序它会编译,我忽略了两者的第一次值(我对编译时间不感兴趣)。

为了找到平均值,我使用了

mean(b1(2:201))

mean(b2(2:201))

结果:

“纵观”:1.634311562062418e-05秒(0.000016343)

“开始时”:2.832598989758290e-05秒(0.000028326)

有趣的是(或许不知道,谁知道)只在需要时定义变量,整个程序的传播速度几乎快两倍。

我不知道这是否是因为MATLAB分配内存的方式(也许它只是抓取了一个巨大的块,并且不需要在每次定义变量时都分配更多?)或者分配速度是否正好如此之快,以至于额外的代码行黯然失色。

注意:正如Divakar指出的那样,使用数组时里程可能会有所不同。但是,当变量的大小没有改变时,我的测试应该成立。

tl; dr将变量设置为零只是为了稍后更改