在MATLAB函数中,使用以下代码:
function stuff()
if a == 2
do1();
else
do2();
end
end
此代码放置在模拟循环内,每秒被调用1000次或多次。 if
语句仅在函数的第一次调用中起作用,在使用do1
或do2
之后,变量a
将不再更改。
如何防止这种if
语句浪费处理时间?基本上,我该如何告诉Matlab,不要再检查if语句,而只调用在第一次调用stuff
中被选中的那个函数?
答案 0 :(得分:5)
与您的看法相反,这不是问题,编译器(应该)自动为您执行此优化。参见例如Loop-invariant code motion。
您可以帮助编译器做的事情就是将检查的计算结果作为标志移到外部,例如
flag = a==2;
for i = 1:100
stuff(flag)
end
然后,您只需要进行一次计算即可,编译器很清楚该值不会更改。
注意:显然,如果您的支票确实是a==2
,则不会有太大的不同。
编辑:我还不能确定MATLAB是否会自动执行此操作。但是,这只是为您完成的第一层优化。所有现代处理器都使用所谓的Branch预测器,例如这个出色的答案Why is processing a sorted array faster than processing an unsorted array?或这个wiki page。简而言之,处理器会猜测if语句的结果,如果它是正确的,那么一切都会更快。我认为可以说处理器在您的所有情况下都可以正确猜测。
TLDR:不用担心。
答案 1 :(得分:3)
鉴于以上评论,看来您实际上正在寻找的是一种动态选择要在仿真中运行的函数的方法。该选择应该是动态的(您不知道在运行时使用哪个函数),但是选择只能执行一次。使用函数句柄可以轻松实现:https://www.mathworks.com/help/matlab/function-handles.html
这里是一个例子:
2^n
如果多次运行此函数,您会注意到func1或func2的(随机)选择将意味着您不会每次都运行相同的功能,尽管整个模拟都使用相同的功能。
答案 2 :(得分:1)
我认为您不会花很多时间来检查if
语句的有效性。但是,由于您特别提到了它仅检查第一次迭代:为什么不这样做呢?所以代替:
for ii = 1:10
if ii == 1
k = 1;
else
k = k + 1;
end
end
你可以做
k = 1;
for ii = 2:10
k = k + 1;
end
因此取消了支票。
NB:当然,伸缩性很差,但是由于这里只是一次迭代,我认为这是一个不错的选择。