有没有办法在MATLAB中执行函数内联? [英] Is there a way to perform function inlining in MATLAB?

查看:151
本文介绍了有没有办法在MATLAB中执行函数内联?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用什么语言功能或外部入侵技术来完成MATLAB中的函数内联功能?令人讨厌的是, Google搜索matlab内联函数揭示了MATLAB的设计者认为内联的意思是用字符串构造一个匿名函数(... wtf?)。

我问的原因是我写了一个需要快速运行的脚本,而且我遇到了很多情况,希望有一个辅助函数处理一些简单的添加或避免逐个错误的情况。但是,函数调用的成本(以 tic / toc 衡量)不值得。我拒绝相信MATLAB会缺少函数内联功能,因为这会阻止分解!



最糟糕的情况是,我可以使用 M4 宏。






编辑:
为了回应吃评论,这里有一种情况,我可能喜欢内联助手:



有一点,我需要循环(是的,我知道)在一个列表中宽度 windowWidth 的所有窗口中:

  lastWindowStartIdx = length(list) -  windowWidth + 1; 
for windowStartIdx = 1:lastWindowStartIdx
display(list [windowStartIdx:windowStartIdx + windowWidth-1]); %我们正在查看的窗口
end

能够计算出那些棘手的,偏离错误的 windowWidth 计算。例如:

  lastWindowStartIdx = calcLastWindowStartIdx(length(list),windowWidth); 
for windowStartIdx = 1:lastWindowStartIdx
display(list [windowStartIdx:calcWindowEndIdx(windowStartIdx,windowWidth)]); %我们正在查看的窗口
end


解决方案

< h2>具体答案:

关于您的示例用例,这实实在在地让我觉得这是一种微观优化。这些加1操作当然不是代码中的瓶颈,因此它不会运行得很快,所以您应该专注于加速大部分计算所在的代码部分。



如果您只想对美学进行修改(在第一次尝试时拼写它)的原因,或者因为您不想跟踪额外的修改,则创建一个函数来处理它如你的例子在我看来是一个不好的选择,因为它使得代码更难以阅读和理解。我建议你简单地创建一个新的变量,如下所示:

  windowOffset = windowWidth  -  1; 
lastWindowStartIdx =长度(列表) - windowOffset;
for windowStartIdx = 1:lastWindowStartIdx
display(list [windowStartIdx:windowStartIdx + windowOffset]);
end



一般答案:



关于如何在MATLAB中创建真正的内联函数的更一般问题,就像在C中一样或C ++,我不相信有任何方法可以做到这一点。我想也许匿名功能可能适合该法案,但在与MATLAB的一些不同类型的函数进行一些简单的时序比较后, / a>我发现一个匿名函数实际上比一个好的函数更慢'子功能进行简单的+1操作。



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

 函数parent_function 
add_one_anon = @(A)A + 1; %#一个匿名函数
add_one_inline = inline('A + 1'); %#一个内嵌函数
函数add_one_nest%#嵌套函数
A = A + 1;
end
%#在这里计时...
end
function A = add_one_sub(A)%#A子函数
A = A + 1;
end

我运行了这些100,000次递增标量值(从1开始)结果如下:

  |时间(秒)
------------ + ------------
subfunction | 0.0507
anonymous | 0.0672
嵌套| 0.0932
inline | 14.7095

如果匿名函数的行为类似于真正的内联函数,我会期望它们是最快的解决方案。

What language feature or outside-the-box hack can I use to accomplish function inlining in MATLAB? Annoyingly, a Google search for "matlab inline function" reveals that MATLAB's designers thought that "to inline" means "to construct an anonymous function out of a string" (...wtf?).

The reason I ask is I am writing a script that needs to run fast, and I am encountering a lot of situations where it would be nice to have a helper function handle some simple addition or something to avoid off-by-one errors. However, the cost of a function call (as measured by tic/toc) would not be worth it. I refuse to believe that MATLAB would lack a function inlining feature because that would discourage decomposition!

Worst case, I could resort to using M4 macros.


EDIT: In response to eat's comment, here is a situation where I might like to inline a helper:

At one point, I need to loop (yeah, I know) over all windows of width windowWidth within a list:

lastWindowStartIdx = length(list) - windowWidth + 1;
for windowStartIdx = 1:lastWindowStartIdx
   display(list[windowStartIdx:windowStartIdx+windowWidth-1]); %the window we're looking at
end

It would be nice to be able to factor out those tricky, off-by-one-error-prone windowWidth calculations. E.g.:

lastWindowStartIdx = calcLastWindowStartIdx(length(list), windowWidth);
for windowStartIdx = 1:lastWindowStartIdx
   display(list[windowStartIdx:calcWindowEndIdx(windowStartIdx, windowWidth)]); %the window we're looking at
end

解决方案

Specific answer:

In reference to your example use-case, this honestly strikes me as a sort of micro-optimization. These plus-one operations are certainly not the bottleneck in your code keeping it from running fast, so you should instead focus on speeding up the parts of your code where the bulk of your computations take place.

If you are only wanting to make this change for aesthetic (spelled it on the first try!) reasons, or because you just don't like keeping track of the extra ones, then creating a function to handle it as in your example is a bad choice in my opinion because it just makes the code that much harder to read and understand. I would suggest simply creating a new variable like so:

windowOffset = windowWidth - 1;
lastWindowStartIdx = length(list) - windowOffset;
for windowStartIdx = 1:lastWindowStartIdx
   display(list[windowStartIdx:windowStartIdx + windowOffset]);
end

General answer:

Regarding your more general question about how to create true inline functions in MATLAB like you can in C or C++, I don't believe there's any way to do this. I thought perhaps that an anonymous function may fit the bill, but after doing some simple timing comparisons with a number of different types of functions in MATLAB I found that an anonymous function is actually slower than a good ol' subfunction for a simple +1 operation.

Here were the sample functions I tested:

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

I ran each of these 100,000 times incrementing a scalar value that started at 1, and here are the results:

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

If anonymous functions acted like true inline functions, I would have expected them to be the fastest solution.

这篇关于有没有办法在MATLAB中执行函数内联?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆