Matlab:局部函数(子函数)是与主函数一起编译还是单独编译?

Matlab: Are local functions (subfunctions) compiled together with main function or separately?

我听说 MATLAB 有一个自动编译函数的功能,如果你像下面的代码一样多次调用一个函数,它可能会产生大量的函数调用开销:

function output = BigFunction( args )
    for i = 1:10000000
        SmallFunction( args );
    end
end

如果我将函数 SmallFunction() 放在与 BigFunction() 相同的文件中作为本地函数调用它是否更快?或者除了将代码从 SmallFunction() 粘贴到 BigFunction() 以优化性能之外,还有什么好的解决方案吗?

编辑:假设函数调用开销是因为需要编译,这可能是错误的。问题是如何在不让代码看起来糟糕的情况下减少开销。

Matlab 对它读入内存的函数进行哈希处理。如果函数作为独立函数存在于其自己的文件中,则仅编译一次。如果将 BigFunction 放入 BigFunction.m 并将 SmallFunction 放入 SmallFunction.m,那么您应该获得编译一次 m 脚本的优化好处。

我的第一个问题的答案是本地函数与另一个文件中的函数执行相同的操作。

第二个问题的一个想法是,如果可能的话,使 SmallFunction() 成为一个内联函数,这样函数调用开销会更少。我在 MathWorks forum 中找到了更多关于函数调用性能的信息,并将问题和答案粘贴在下面:

问题:

I have 7 different types of function call:

  1. An Inline function. The body of the function is directory written down (inline).

  2. A function is defined in a separate MATLAB file. The arguments are passed by the calling function (file-pass).

  3. A function is defined in a separate MATLAB file. The arguments are provided by referencing global variables; only indices are provided by the calling function (file-global).

  4. A nested function. The arguments are passed by the enclosing function (nest-pass).

  5. A nested function. The arguments are those shared with the enclosing function; only indices are provided by the enclosing function (nest-share).

  6. A sub function. The arguments are passed by the calling function (sub-pass).

  7. A sub function. The arguments are provided by referencing global variables; only indices are provided by the calling function (sub-global).

I would like to know which function call provides better performance than the others in general.

此处粘贴了 MathWorks 支持团队的回答:

The ordering of performance of each function call from the fastest to the slowest tends to be as follows:

inline > file-pass = nest-pass = sub-pass > nest-share > sub-global > file-global

(A>B means A is faster than B and A=B means A is as fast as B)

First, inline is the fastest as it does not incur overhead associated with function call.

Second, when the arguments are passed to the callee function, the calling function sets up the arguments in such a way that the callee function knows where to retrieve them. This setup associated with function call in general incurs performance overhead, and therefore file-pass, nest-pass, and sub-pass are slower than inline.

Third, if the workspace is shared with nested functions and the arguments to a nested function are those shared within the workspace, rather than pass-by-value, then performance of that function call is inhibited. If MATLAB sees a shared variable within the shared workspace, it searches the workspace for the variable. On the other hand, if the arguments are passed by the calling function, then MATLAB does not have to search for them. The time taken for this search explains that type nest-share is slower than file-pass, nest-pass, and sub-pass.

Finally, when a function call involves global variables, performance is even more inhibited. This is because to look for global variables, MATLAB has to expand its search space to the outside of the current workspace. Furthermore, the reason a function call involving global variables appears a lot slower than the others is that MATLAB Accelerator does not optimize such a function call. When MATLAB Accelerator is turned off with the following command,

feature accel off the difference in performance between inline and file-global becomes less significant.

Please note that the behaviors depend largely on various factors such as operating systems, CPU architectures, MATLAB Interpreter, and what the MATLAB code is doing.