在循环中使用length()是否有效?

jef*_*eff 5 performance matlab loops time-complexity variable-length

当我在MATLAB中迭代一个向量时,我有很多情况,

所以我这样做:

len = length(vector)
for i=1:len
 do_something();
end
Run Code Online (Sandbox Code Playgroud)

但这只是一种直觉,说" length()每次都要阻止调用函数".这是真的吗?或者在时间要求方面与此相同:

for i=1:length(vector)
 do_something();
end
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助!

Sam*_*rts 7

如果你担心性能或速度 - 不要担心,真的.它不会产生任何明显的差异.@David在他的回答中提供了一些时间来支持这一点.

在美学方面,我通常会写出它的价值

for i = 1:numel(v)
    doSomething(v(i))
end
Run Code Online (Sandbox Code Playgroud)

我倾向于选择numellength,因为length给你最长阵列尺寸的长度,而不是第一个维度的长度.如果你总是确定它是矢量它们是相同的,但我尽量避免这种假设.

当然,如果我需要numel(v)单独访问,那么将它提取到中间变量vNum并写入是值得的for i = 1:vNum.

如果你对for循环索引的语义感兴趣,那么它比你想象的要复杂得多.在编写时for i = 1:N,MATLAB并不总是简单地创建向量1:N,然后迭代它.例如,你可以写

for i = 1:realmax
    i
end
Run Code Online (Sandbox Code Playgroud)

要么

for i = 1:Inf
    i
end
Run Code Online (Sandbox Code Playgroud)

甚至

for i = Inf:-1:1
    i
end
Run Code Online (Sandbox Code Playgroud)

它会工作(按下Ctrl-C逃脱).在这种情况下,MATLAB不会将循环索引创建为向量,但它不能,因为它太大了.

解析器具有比这更复杂的逻辑,具有多个边缘情况和优化的知识.有时它会在循环之前创建循环索引,有时会在运行中.除非您可以访问MATLAB源代码,否则我保证您无法对所有内部结构进行二次猜测.

还要注意,循环索引不必是向量; 如果你提供一个数组,MATLAB循环遍历列.例如,

for i = magic(3)
    i
end
Run Code Online (Sandbox Code Playgroud)

依次显示数组的列.类似地,您可以提供一个单元格数组,它将遍历单元格(NB索引是单元格,而不是单元格中的元素).

出于这个原因,我有时会写

for vElement = v
    doSomething(vElement)
end
Run Code Online (Sandbox Code Playgroud)

而不是上面使用的第一个模式numel.

当然,根据应用程序,矢量化doSomething和调用可能会更好doSomething(v).

最后一件事 - 我们到目前为止谈论的是整数指数,但请记住冒号运算符可以有任何增量,例如pi:sqrt(2):10; 并记住结肠操作符不一样linspace,也不会给你相同的答案.