我的问题并不是明确依赖于一段代码,而是更具概念性。
与某些编程语言不同,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;
一方面,无缘无故地拥有这些额外的代码行似乎有点浪费。但另一方面,有一点意义是,一次为程序分配所有内存而不是在运行时分散会更快。
有没有人有一点见解?
答案 0 :(得分:5)
将Initializing at start:
代码复制并粘贴到MATLAB编辑器窗口中,您会收到如下警告 -
如果你进入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将变量设置为零只是为了稍后更改