Function 有没有在MATLAB中执行函数内联的方法?

Function 有没有在MATLAB中执行函数内联的方法?,function,matlab,syntax,macros,inline,Function,Matlab,Syntax,Macros,Inline,在MATLAB中,我可以使用什么样的语言特性或外部技巧来实现函数内联?令人烦恼的是,MATLAB的设计者认为“内联”意味着“用字符串构造匿名函数”(…wtf?) 我问这个问题的原因是我正在编写一个需要快速运行的脚本,并且我遇到了很多情况,在这些情况下,让一个助手函数处理一些简单的加法或避免一个接一个的错误会很好。但是,函数调用的成本(由tic/toc衡量)是不值得的。我不相信MATLAB会缺少函数内联特性,因为这会阻碍分解 最糟糕的情况是,我可以求助于使用宏 编辑: 作为对eat评论的回应,以

在MATLAB中,我可以使用什么样的语言特性或外部技巧来实现函数内联?令人烦恼的是,MATLAB的设计者认为“内联”意味着“用字符串构造匿名函数”(…wtf?)

我问这个问题的原因是我正在编写一个需要快速运行的脚本,并且我遇到了很多情况,在这些情况下,让一个助手函数处理一些简单的加法或避免一个接一个的错误会很好。但是,函数调用的成本(由
tic/toc
衡量)是不值得的。我不相信MATLAB会缺少函数内联特性,因为这会阻碍分解

最糟糕的情况是,我可以求助于使用宏


编辑: 作为对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
计算结果一一剔除,那就太好了。例如:

lastWindowStartIdx = calcLastWindowStartIdx(length(list), windowWidth);
for windowStartIdx = 1:lastWindowStartIdx
   display(list[windowStartIdx:calcWindowEndIdx(windowStartIdx, windowWidth)]); %the window we're looking at
end
具体答复: 在参考您的示例用例时,我真的觉得这是一种微观优化。这些加一操作当然不是代码中阻止其快速运行的瓶颈,因此您应该专注于加快代码中大部分计算发生的部分

如果您只是出于美观(第一次尝试时就拼写了!)的原因,或者因为您不喜欢跟踪额外的代码,那么在我看来,创建一个函数来处理它是一个错误的选择,因为它只会使代码更难阅读和理解。我建议简单地创建一个新变量,如下所示:

windowOffset = windowWidth - 1;
lastWindowStartIdx = length(list) - windowOffset;
for windowStartIdx = 1:lastWindowStartIdx
   display(list[windowStartIdx:windowStartIdx + windowOffset]);
end
一般答覆: 关于你在C++中如何在Matlab中创建真的更一般的问题,我不相信有任何方法可以做到这一点。我认为也许an符合要求,但在与a进行一些简单的计时比较后,我发现对于简单的+1操作,匿名函数实际上比好的ol慢

以下是我测试的示例函数:

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
我将从1开始的标量值递增100000次,结果如下:

            | Time (sec)
------------+------------       
subfunction |   0.0507
anonymous   |   0.0672
nested      |   0.0932
inline      |  14.7095

如果匿名函数的作用类似于真正的内联函数,我早就认为它们是最快的解决方案。

< P>简而言之,在C++中,不能用C++术语“代码>内联<代码> >函数。您可能已经知道了这一点,但是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

是否愿意显示任何代码,其中您的
在衬里中
确实是有益的?您所说的“一个错误关闭”是什么意思?Thanks@eat我编辑了我的问题,加入了一个例子,当你说“拒绝相信Matlab没有内联”时,这让我觉得你对Matlab不是很熟悉。MathWorks不关心方法和函数调用的性能,特别是在分解方面。新的MCOS类的语法支持分解设计,其方法调用比旧类慢得多,存在愚蠢的语法相关性能怪癖,并且存在一个错误,使64位Matlab中的旧式方法调用开销加倍。让M代码运行得更快的官方方法是将其矢量化。“内联”不是他们的风格。(火焰熄灭。)@Andrew你说得对,我是Matlab新手。对不起,我问题中的语气太粗暴了。我只是觉得很奇怪(主要是基于类似C语言和Python的经验),一种语言实际上不鼓励反编译。不用担心。我也有点生气了。我花了很长时间(大约一年多)才习惯了用C、Java和Perl编写Matlab代码。真的不一样。我并不是说你不应该希望在Matlab中内联和支持快速的小对象。(我也希望如此,而且非常希望如此。)只是你不应该因为没有得到它而感到惊讶。公平地说,对于这个特定的例子来说,这确实是一个很好的解决方案。但在我接受你的回答之前,你能回答我的实际问题吗,那就是如何(甚至是一种黑客的方式)完成内联?谢谢@乔恩·罗德里格斯:你已经提到M4了。其他代码生成技术也可以工作。MATLAB有一个JIT,所以假设他们做对了(这对于MathWorks来说不一定是一个好的假设),就没有太多理由手动指定内联。不管怎样,许多C和C++编译器都忽略了用户提供的内联指令,因为编译器比人类更善于理解这些指令。在Matlab JIT中做广义内联可能会非常困难,因为实际调度的函数取决于所有输入变量的类型以及特定函数调用时Matlab路径的状态。有关各种函数调用类型的基准,请参阅。(这是一种简化,因为它不考虑输入和输出参数的成本。)在您的基准中,考虑将嵌套函数拆分为单独的基准函数。它的存在将封闭的父函数更改为“静态工作区”,并可能对如何从父函数中调用其他函数类型产生副作用(好的或坏的)。@Andrew:最初几次运行基准测试时,我没有在其中嵌套函数,在我添加它之后,我没有看到任何明显的计时结果差异。作为补充说明,
窗口范围
可以通过实际使用
lower
参数使其更通用,如果您希望它不是1。