函数句柄 运行 时的 Matlab 解析

Matlab parsing at run-time of function handles

我的问题:给定一个函数句柄,matlab 是在每次需要评估时解析字符串,还是只解析一次然后缓存它?

例子

考虑巧妙的功能

function [] = foo(func)
for j=1:1e4
    func(j);
end

和剧本

func1 = @(x) 5*abs(x)^2
function foo(func1);

在运行时,Matlab需要将@(x) 5*abs(x)^2解释为一个函数。在这个例子中,它是执行一次还是执行一千次?

首先@(x)cos(x)不是一个字符串,它是一个anonymous function declaration。当您创建一个匿名函数时,MATLAB 实际上会创建一个函数对象,其中包含它需要 运行 的所有信息。然后可以将此匿名函数传递给各种函数,甚至可以将其保存到文件中。因此,它只构造一次并计算多次。

计算时,MATLAB 不做任何缓存,因此多次调用具有相同输入的相同匿名函数会导致每次计算匿名函数的内容。

如果您想获得有关您的匿名函数的更多信息,包括该函数的本地工作区,您可以使用 functions 函数

f = @(x)cos(x);

functions(f)

%            function: '@(x)cos(x)'
%                type: 'anonymous'
%                file: ''
%           workspace: {[1x1 struct]}
%    within_file_path: '__base_function'

也就是说,在您的示例中,它可以 真正 减少为 function handle 而不是匿名函数,因为您将所有输入参数直接传递给 cos 而不修改它们。如您所见,这具有不同的内部表示,并且从一些初步基准测试来看,它似乎稍微快一些。

f = @cos

functions(f)

%    function: 'cos'
%        type: 'simple'
%        file: ''

以及快速基准测试

function benchit
    fprintf('Anonymous function: %0.4f\n', timeit(@option1));
    fprintf('Function handle:    %0.4f\n', timeit(@option2));
end

function option2()
    f = @(x)cos(x);
    for k = 1:10000
        f(k);
    end
end

function option1()
    f = @cos;
    for k = 1:10000
        f(k);
    end
end

结果(差别不大)

Anonymous function: 0.0056
Function handle:    0.0049

还有一些东西

  • 创建匿名函数时,匿名函数声明必须仍然遵守MATLAB的所有标准语法规则,否则将无法创建。例如,以下将在匿名函数 creation 期间抛出错误,因为它是无效语法

    func = @(x)thing]
    

    Error: Unbalanced or unexpected parenthesis or bracket.

  • 当你评估一个匿名函数时(在它成功创建之后),就像评估任何其他函数一样匿名函数可以抛出错误并且错误取决于输入。

    func = @(x) x + [1 2];
    
    func([3 4])
    %   4   6
    
    % Now we're going to pass an array that isn't 1 x 2
    func([5 6 7])
    

    Matrix dimensions must agree.
    Error in @(x)x+[1,2]