在MATLAB中使用匿名函数会降低性能...其他人是否注意到了这一点? [英] Slow performance using anonymous functions in MATLAB... have others noticed this?

查看:405
本文介绍了在MATLAB中使用匿名函数会降低性能...其他人是否注意到了这一点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了重构我的MATLAB代码,我认为我会在函数编程的启发下将函数作为参数传递(MATLAB称为匿名函数).

In order to refactor my MATLAB code, I thought I'd pass around functions as arguments (what MATLAB calls anonymous functions), inspired by functional programming.

但是,性能似乎受到了严重打击.在下面的示例中,我比较了不同的方法. (代码段包装在一个函数中,以便能够使用子函数)

However, it seems performance is hit quite severely. In the examples below, I compare different approaches. (The code snippet is wrapped in a function in order to be able to use subfunctions)

我得到的结果是直接为0秒,使用子函数几乎为0秒,使用匿名函数为5秒.我正在OS X 10.6和C2D 1.8 GHz上运行MATLAB 7.7(R2007b).

The result I get is 0 seconds for direct, almost 0 seconds using a subfunction, and 5 seconds using anonymous functions. I'm running MATLAB 7.7 (R2007b) on OS X 10.6, on a C2D 1.8 GHz.

任何人都可以运行代码并查看得到的内容吗?我对Windows的性能特别感兴趣.

Can anyone run the code and see what they get? I'm especially interested in performance on Windows.

function [] = speedtest()


clear all; close all;

function y = foo(x)
    y = zeros(1,length(x));
    for j=1:N
        y(j) = x(j)^2;
    end
end

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


%% direct
t = cputime;

y = zeros(1,N);
for i=1:N
    y(i) = x(i)^2;
end

r1 = cputime - t;

%% using subfunction
t = cputime;
y = foo(x);
r2 = cputime - t;

%% using anon function
fn = @(x) x^2;

t = cputime;

y = zeros(1,N);
for i=1:N
    y(i) = fn(x(i));
end

r3 = cputime-t;

[r1 r2 r3]

end

推荐答案

您在欺骗嵌套函数. :)匿名函数在循环内被调用,因此您要衡量调用它的成本100,000次.嵌套函数仅被调用一次,因此其函数调用开销可以忽略不计.为了比较调用匿名函数和命名函数的成本,您应该让嵌套函数执行与匿名函数相同的工作,然后从循环内部调用它.

You're cheating with the nested function. :) The anonymous function is being called inside a loop, so you're measuring the cost of calling it 100,000 times. The nested function only gets called once, so its function call overhead is negligible. To compare the cost of calling anonymous vs named functions, you should have the nested function do the same work as the anonymous function and then call it from inside a loop, too.

我做到了,仍然得到了相似的结果.匿名功能要慢20倍左右.

I did that and still got similar results. The anonymous function is about 20 times slower.

但是,您仍然可以将函数句柄与非匿名函数一起使用,并且其性能不如匿名函数那样高.这可以与嵌套函数(如原始测试中的foo)一起使用,也可以与非嵌套子函数(不用作闭包,并且可能具有较少的开销)一起使用.

However, you can still use function handles with non-anonymous functions, and that doesn't have the same performance hit as anonymous functions. This works with either nested functions (as with the foo in your original test) or non-nested subfunctions (which don't act as closures and may have less overhead).

function [] = speedtest()

function y = foo(x)
    y = x^2;
end

r = struct;

...

%% using nested function through function handle
fn = @foo;
y = zeros(1,N);
t = cputime;
for i=1:N
    y(i) = fn(x(i));
end
r.nested_handle = cputime - t;

...

%% using subfunction through function handle
fn = @subfunction_foo;
y = zeros(1,N);
t = cputime;
for i=1:N
    y(i) = fn(x(i));
end
r.subfunction_handle = cputime - t;

...

end % end function speedtest

function y = subfunction_foo(x)
y = x^2;
end

我在Windows的R2009b上得到了它.

I get this on R2009b in Windows.


>> speedtest
                direct: 0
                nested: 0.0469
         nested_handle: 0.0781
           subfunction: 0.0313
    subfunction_handle: 0.0313
             anonymous: 1.2344

另一种看待它的方法是对代码进行结构化,以使其矢量化"并在数组上运行,从而减少了函数调用的次数,而函数调用的成本无关紧要.那将是Matlab的惯用语:典型的性能建议是忽略函数调用和循环的开销,因为无论如何您应该对较大的参数进行较少的调用.

Another way to look at it is to structure your code so it's "vectorized" and operates on arrays, reducing the number of function calls and the cost of the function call doesn't matter so much. That would be more idiomatic Matlab: typical performance advice is to ignore the cost of function calls and loops because you ought to be doing fewer calls on larger arguments anyway.

这篇关于在MATLAB中使用匿名函数会降低性能...其他人是否注意到了这一点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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