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

Performance 初始化或预分配的最佳实践-MATLAB,performance,matlab,Performance,Matlab,我的问题不是明确地依赖于一段代码,而是更概念化的 与某些编程语言不同,MATLAB不要求在使用变量之前对其进行明确初始化。例如,在脚本文件的中途定义“myVector”是完全有效的: myVector = vectorA .* vectorB 我的问题是:将变量(如上面的“myVector”)初始化为零,然后给它们赋值,或者在整个程序中不断初始化,这是更快的吗 下面是我所说内容的直接比较: 始终初始化: varA = 8; varB = 2; varC = varA - varB; varD

我的问题不是明确地依赖于一段代码,而是更概念化的

与某些编程语言不同,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;
一方面,毫无理由地拥有这些额外的代码行似乎有点浪费。然而,另一方面,有一点道理,一次为一个程序分配所有内存会更快,而不是分散在运行时


有人对此有点了解吗?

将您的
开始初始化:
代码复制并粘贴到MATLAB编辑器窗口中,您将得到如下警告-

如果你进入
详细信息
,你会读到这篇文章-

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...
在我们的例子中,出现此警告的原因是
代码未使用所有值。因此,这澄清了初始化/预分配对这种情况没有帮助


我们应该什么时候预分配? 根据我的经验,当您以后需要索引到它的一部分时,预分配会有所帮助

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

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

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

好吧!我做了一些测试,下面是结果

这是我用于“贯穿”变量赋值的代码:

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
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
以下是“开始时”变量赋值的代码:

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
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))

结果是:

“全程”:1.634311562062418e-05秒(0.000016343)

“启动时”:2.8325989758290E-05秒(0.000028326)

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

我不知道这是因为MATLAB分配内存的方式(可能它只是占用了一大块内存,不需要每次定义变量时都继续分配更多内存),还是因为分配速度太快,额外的代码行让它黯然失色

注意:正如Divakar指出的,使用阵列时里程可能会有所不同。然而,当变量的大小不变时,我的测试应该是正确的


tl;dr将变量设置为零,只是稍后更改它是很慢的

我注意到,如果您一直延长向量(例如在循环内),MATLAB会发出警告,以进行初始化。事实上,这正是我提出这个问题的原因。澄清一下:当变量的大小发生变化时,你应该初始化为最大大小,这样MATLAB就不必继续分配更多的内存,而当大小没有变化时,你应该在需要时定义变量?@h3half我想这就是
索引的地方,在第2部分中讨论过或有点涉及到的内容。@h3half我一定是以
最大大小写的,刚刚编辑过。