MATLAB:脚本函数中常量变量的缓慢读入

MATLAB:脚本函数中常量变量的缓慢读入,matlab,performance,function,eval,Matlab,Performance,Function,Eval,在最新的MATLAB版本中,我使用了脚本中本地函数的特性来简化和缩短代码 现在我有一个简单的脚本,可以进行数学计算,在for循环中可以进行数百万次迭代。从循环中,我提取了用于多个独立循环的数学部分。但是,我有速度和常量变量的问题,需要在函数中。如果我不使用本地函数编写代码,速度会很快,但如果使用该函数,速度会慢10倍 我认为这是由于函数中变量的重复读入。如果是从文件中读取,则需要花费很长时间。我取得的最好成绩是使用evalin函数从基本工作区调用变量。它可以工作,但正如我提到的,它比没有单独的本

在最新的MATLAB版本中,我使用了脚本中本地函数的特性来简化和缩短代码

现在我有一个简单的脚本,可以进行数学计算,在
for
循环中可以进行数百万次迭代。从循环中,我提取了用于多个独立循环的数学部分。但是,我有速度和常量变量的问题,需要在函数中。如果我不使用本地函数编写代码,速度会很快,但如果使用该函数,速度会慢10倍

我认为这是由于函数中变量的重复读入。如果是从文件中读取,则需要花费很长时间。我取得的最好成绩是使用
evalin
函数从基本工作区调用变量。它可以工作,但正如我提到的,它比没有单独的本地函数慢10倍

如何克服这个问题

结构如下所示:

load('Data.mat'); r=1; %Reads variables L,n

for Lx = L1:Ld:L2
    for x = x1:d:x2
        Yx(r) = myF(x); r=r+1
    end
end

%A few more different loops...

function y = myF(x)
    L = evalin('base','L');
    n = evalin('base','n');
    ...
    a = (x-L)^2; b = sin(a)-n/2; ... y=b*a/L;
end

您需要显式地将变量作为附加输入参数传递给
myF
,这样就不必每次都加载它们。这样,您就不必担心调用
evalin
或在循环的每次迭代中从文件中加载它们

load('Data.mat'); r=1; %Reads variables L,n

for Lx = L1:Ld:L2
    for x = x1:d:x2
        Yx(r) = myF(x, L, n); r=r+1
    end
end

function y = myF(x, L, n)
    a = (x-L)^2; b = sin(a)-n/2;
    y=b*a/L;
end
如果出于某种原因,您无法修改
myF
,只需将整个内容转换为一个函数,并将
myF
作为子函数,它将自动访问父函数中的任何变量。在这种情况下,您还需要将
load
的输出分配给一个变量

第三个选择是仔细查看<代码> Myf,并考虑是否可以对内容进行矢量化,以便实际上不必连续调用它数次。

您可以通过执行以下操作将其矢量化

[Lx, x] = ndgrid(L1:Ld:L2, x1:d:x2);
a = (x - L).^2;
b = sin(a) - (n / 2);
Yx = (b .* a) ./ L;

第一种方法效果很好,忘记了这一点:D但是第二种方法看起来更好,因为一遍又一遍地将相同的常量变量解析到函数中是非常困难的。但是,对于第二种方法,我不能简单地从文件中加载所有变量,我必须指定所有变量:
使用load时出错
尝试将“L”添加到静态工作区。
矢量化也是一种很好的方法,但我无法在代码中实现它,因为我需要的不仅仅是计算,就像从数据和一些
if
条件中找到正确的值和预测值一样。@Klaidonis right,您真的应该指定一个当前使用相同的第一个方法的值。我认为仍有可能提高绩效。我尝试将
load
放在
myF
函数中,使用
if isempty(L)
仅在第一次执行时加载,并将这些常量变量定义为
persistent
。然而,速度下降了50%以上。它只是为了检查
if
数百万次吗?尽管如此,第一种方法目前是最快的。对于第二种方法,我不喜欢所有变量都是共享的,如果您定义了一个新的变量,您很容易忽略这样一个变量已经存在。
[Lx, x] = ndgrid(L1:Ld:L2, x1:d:x2);
a = (x - L).^2;
b = sin(a) - (n / 2);
Yx = (b .* a) ./ L;