Labfans是一个针对大学生、工程师和科研工作者的技术社区。 | 论坛首页 | 联系我们(Contact Us) |
![]() |
![]() |
#1 |
高级会员
注册日期: 2019-11-21
帖子: 3,006
声望力: 66 ![]() |
![]()
优化我的MATLAB代码时,我偶然发现了一个关于匿名函数的怪异问题。
就像我在该线程中意识到的那样,有时匿名函数的运行速度非常慢。但是,只需对函数进行最少的更改,它就可以与子函数或嵌套函数一样快地运行。 我使用了这个(简单的)测试文件来重现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; 在开始分析所有功能之前,我想知道是否有人对此行为有解释? PS:我知道“向量化”方法要快得多,但是在我的情况下,求解器将针对每个可变时间步长评估函数,因此这不是一种选择。 回答: 看起来在'fn2'的情况下,Matlab优化器能够内联该函数,而在'fn1'的情况下却无法这样做。 这可能与Matlab有关参数和返回值的标量,复杂性或结构的知识有关。它可能会弄清楚“ i”(调用现场的参数)必须是标量,实数和非结构化的。给定一个标量参数,然后尝试找出函数的行为。对于'fn2',Matlab的优化程序静态确定其始终可以将'double()'的所有可能结果放入目标变量'y(i)'。由于某些原因,优化器的设计者才知道,因此Matlab无法对“ fn1”得出相同的结论。可能存在一些非显而易见的极端情况,或者'^'缺少优化器依赖的一些元数据。无论如何,结果是在'fn1'的情况下,Matlab显然在每次迭代时都会重新评估该函数。 无论如何,静态优化动态语言在编译器设计中是一件黑手艺。 更多&回答... |
![]() |
![]() |