我的问题:给定一个函数句柄,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
解释为函数。在这个例子中,它是一次还是一千次?
答案 0 :(得分:6)
首先,@(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的所有标准语法规则,否则无法创建。例如,以下内容会在匿名函数创建期间抛出错误,因为它是无效的语法
func = @(x)thing]
错误:不平衡或意外的括号或括号。
当您评估一个匿名函数(在它成功创建之后)时,它就像评估任何其他函数一样,匿名函数可能会抛出错误并且错误取决于输入。
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])
矩阵尺寸必须一致。
中的错误
@(x)x + [1,2]