我可以使用哪种语言功能或开箱即用的黑客来完成MATLAB中的函数内联?令人恼火的是,a Google search for "matlab inline function"揭示了MATLAB的设计者认为“内联”意味着“用字符串构造一个匿名函数”(... wtf?)。
我问的原因是我正在编写一个需要快速运行的脚本,而且我遇到很多情况,让一个帮助函数处理一些简单的添加或者一些东西来避免一个一个很好错误。但是,函数调用的成本(由tic/toc
测量)不值得。我拒绝相信MATLAB缺少函数内联功能,因为这会阻止分解!
最糟糕的情况是,我可以使用M4宏。
编辑: 在回应eat的评论时,我想在这里帮助内联帮助:
有一次,我需要在列表中的所有宽度为windowWidth
的窗口上循环(是的,我知道):
lastWindowStartIdx = length(list) - windowWidth + 1;
for windowStartIdx = 1:lastWindowStartIdx
display(list[windowStartIdx:windowStartIdx+windowWidth-1]); %the window we're looking at
end
能够将那些棘手的,逐个错误的windowWidth
计算分解出来会很好。 E.g:
lastWindowStartIdx = calcLastWindowStartIdx(length(list), windowWidth);
for windowStartIdx = 1:lastWindowStartIdx
display(list[windowStartIdx:calcWindowEndIdx(windowStartIdx, windowWidth)]); %the window we're looking at
end
答案 0 :(得分:9)
在参考您的示例用例时,这实际上让我觉得它是一种微优化。这些加一运算肯定不是代码中的瓶颈,使其无法快速运行,因此您应该专注于加速大量计算所发生的代码部分。
如果您只是想要进行美学上的改变(在第一次尝试时拼写!)原因,或者因为您不喜欢跟踪额外的那些,那么创建一个函数来处理它,就像在你的在我看来,示例是一个糟糕的选择,因为它只会使代码更难以阅读和理解。我建议简单地创建一个新的变量:
windowOffset = windowWidth - 1;
lastWindowStartIdx = length(list) - windowOffset;
for windowStartIdx = 1:lastWindowStartIdx
display(list[windowStartIdx:windowStartIdx + windowOffset]);
end
关于如何在MATLAB中创建真正的inline functions的更一般的问题,就像在C或C ++中一样,我不相信有任何方法可以做到这一点。我想也许anonymous function可能适合这个法案,但是在用number of different types of functions in MATLAB进行一些简单的时序比较后,我发现匿名函数实际上比一个好的'subfunction更慢。简单的+1操作。
以下是我测试的示例函数:
function parent_function
add_one_anon = @(A) A+1; %# An anonymous function
add_one_inline = inline('A+1'); %# An "inline" function
function add_one_nest %# A nested function
A = A+1;
end
%# Did the timing here ...
end
function A = add_one_sub(A) %# A subfunction
A = A+1;
end
我运行了这些100,000次,每次增加一个从1开始的标量值,结果如下:
| Time (sec)
------------+------------
subfunction | 0.0507
anonymous | 0.0672
nested | 0.0932
inline | 14.7095
如果匿名函数的行为与真正的内联函数相同,我原本期望它们是最快的解决方案。
答案 1 :(得分:0)
简而言之,在C ++术语中,不能inline
在MATLAB中运行。您可能已经知道这一点,但MATLAB中的循环很慢,您应该用矢量化操作替换它们。
如果你只需要加速函数调用,你可能应该将所有索引预先计算为矢量化操作,然后循环结果。
windows = window_ranges(1, length(list), windowWidth);
for i = 1:size(windows,1),
display(list[windows(i,1):windows(i,2)]);
end
function [ windows ] = window_ranges ( lower, upper, span )
count = upper - span;
windows = zeros(count, 2);
windows(:,1) = 1:count;
windows(:,2) = windows(:,1)+span-1;
end