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

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

问题描述

为了重构我的 MATLAB 代码,我想我应该将函数作为参数传递(MATLAB 称之为匿名函数),受到函数式编程的启发.

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

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

谁能运行代码看看他们得到了什么?我对 Windows 上的性能特别感兴趣.

function [] = speedtest()清除所有;关闭所有;函数 y = foo(x)y = 零(1,长度(x));对于 j=1:Ny(j) = x(j)^2;结尾结尾x = linspace(-100,100,100000);N = 长度(x);%% 直接的t = 处理器时间;y = 零(1,N);对于 i=1:Ny(i) = x(i)^2;结尾r1 = cputime - t;%% 使用子功能t = 处理器时间;y = foo(x);r2 = cputime - t;%% 使用匿名函数fn = @(x) x^2;t = 处理器时间;y = 零(1,N);对于 i=1:Ny(i) = fn(x(i));结尾r3 = cputime-t;[r1 r2 r3]结尾

解决方案

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

我这样做了,但仍然得到了类似的结果.匿名函数大约慢 20 倍.

但是,您仍然可以将函数句柄与非匿名函数一起使用,这与匿名函数的性能损失不同.这适用于嵌套函数(与原始测试中的 foo 一样)或非嵌套子函数(它们不充当闭包并且可能具有较少的开销).

function [] = speedtest()函数 y = foo(x)y = x^2;结尾r = 结构;...%% 通过函数句柄使用嵌套函数fn = @foo;y = 零(1,N);t = 处理器时间;对于 i=1:Ny(i) = fn(x(i));结尾r.nested_handle = cputime - t;...%% 通过函数句柄使用子函数fn = @subfunction_foo;y = 零(1,N);t = 处理器时间;对于 i=1:Ny(i) = fn(x(i));结尾r.subfunction_handle = cputime - t;...end % 结束函数速度测试函数 y = subfunction_foo(x)y = x^2;结尾

我在 Windows 的 R2009b 上得到了这个.

<前>>> 速度测试直接:0嵌套:0.0469嵌套句柄:0.0781子功能:0.0313子功能句柄:0.0313匿名:1.2344

另一种看待它的方法是构建您的代码,使其向量化"并在数组上操作,减少函数调用的数量,并且函数调用的成本并不那么重要.这将是更惯用的 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)

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.

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

解决方案

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.

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

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

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

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天全站免登陆