MATLAB:匿名函数的性能问题

时间:2011-03-19 02:49:51

标签: performance matlab anonymous-function

优化我的MATLAB代码,我偶然发现了一个关于匿名函数的奇怪问题。

就像in this thread我意识到的那样,有时匿名函数的运行速度非常慢。 但是对函数的更改很少,它的运行速度与子函数或嵌套函数一样快。

我使用这个(简单的)测试文件来重现Windows 7 64位下Matlab R2010b的行为:

clear all; close all; clc;

% functions
fn1 = @(x) x^2;
fn2 = @(x) double(x^2);

% variables
x = linspace(-100,100,100000);
N = length(x);

%% anonymous function
y = zeros(1,N);
t = tic;
for i=1:N
    y(i) = fn1(x(i));
end
tm.anonymous_1 = toc(t);

%% anonymous function (modified)
y = zeros(1,N);
t = tic;
for i=1:N
    y(i) = fn2(x(i));
end
tm.anonymous_2 = toc(t);

%% print
tm

我得到的结果是:

tm = 

    anonymous_1: 1.0605
    anonymous_2: 0.1217

正如您所看到的,第一种方法慢了大约10倍。 我不知道是什么触发了这种加速/减速。 我尝试了不同的东西,得到了几乎相同(快速)的时间:

fn2 = @(x) 1 * x^2;
fn2 = @(x) 0 + x^2;
fn2 = @(x) abs(x^2);
fn2 = @(x) x*x;


在我开始分析我的所有功能之前, 我想知道是否有人对此行为有解释?


P.S。:我知道“矢量化”方法要快得多,但在我的情况下,求解器将评估每个可变时间步的函数,因此这不是一个选项。

2 个答案:

答案 0 :(得分:8)

似乎在'fn2'的情况下,Matlab优化器能够内联函数,而在'fn1'的情况下它不能这样做。

这可能与Matlab对参数和返回值的标量或复杂性或结构的了解有关。它可能会发现“我”(呼叫站点的参数)必然是标量的,真实的和非严格的。给定一个标量参数,然后尝试找出函数的行为。在'fn2'的情况下,Matlab的优化器静态地确定它总是能够将'double()'的所有可能结果拟合到目标变量'y(i)'中。由于某些原因只有优化器的设计者知道,Matlab无法得出'fn1'的相同结论。也许有一些非明显的角落情况,或者'^'缺少优化器所依赖的某些元数据。无论如何,结果是在'fn1'的情况下,Matlab显然在每次迭代时重新评估函数。

无论如何,静态优化动态语言在编译器设计中是一种黑色艺术。

答案 1 :(得分:0)

我认为使函数的返回类型独立于其参数的类型使得Matlab更容易优化。顺便说一句,y = fn1(x);y = fn2(x);在运行时间方面具有大致相同的比例,因此它不是标量或复杂参数的影响。