4

我有一个包含属性的类(假设类文件的名称是inputvar),

我将它用作两个不同函数的输入参数,它们具有完全相同的计算,但代码略有不同,我将在稍后解释。

对于第一个函数(假设名称是 myfun1),我这样编写输入参数:

f = myfun1 (inputvar)

因此,每次我想在函数内部使用类中的变量时,我都必须调用inputvar.var1,inputvar.var2等。

对于第二个函数(myfun2),我在输入参数中写入了类中的每个变量,所以它看起来像这样:

f = myfun2 (inputvar.var1, inputvar.var2, ... etc )

在函数内部,我只需要使用var1var2等,而不必包含类的名称。

运行这两个函数后,我发现myfun2运行速度比 快很多myfun1,大约 60%(我使用了 tic-toc)。

有人可以向我解释为什么会这样吗?

4

2 回答 2

3

参考:_

MATLAB 使用通常称为“写入时复制”的系统来避免在函数工作区中复制输入参数,除非您修改输入参数。如果您不修改输入参数,MATLAB 将避免制作副本。例如,在这段代码中:

函数 y = functionOfLargeMatrix(x) y = x(1); MATLAB 不会在 functionOfLargeMatrix 的工作区中复制输入,因为 x 在该函数中没有被更改。另一方面,如果你调用了这个函数:

函数 y = functionOfLargeMatrix2(x) x(2) = 2; y = x(1); 然后 x 在 functionOfLargeMatrix2 的工作空间内被修改,因此必须制作一个副本。

根据上面的说法,当您直接传递一个类对象并更改该对象的任何成员时,将应用该类的整个复制操作。

另一方面,将类成员作为单独的参数提供,复制操作仅适用于函数中修改的相关成员,从而加快执行速度。

于 2013-07-29T19:45:13.157 回答
3

我发现在 Matlab 中访问属性非常慢。我还没有找到解决方法,但在这里找到了一些基本的想法:http: //blogs.mathworks.com/loren/2012/03/26/considering-performance-in-object-orienting-matlab-code/

但是这篇文章只谈论避免可怕的、糟糕的表现。即使使用最简单的属性,性能也充其量是平庸的。

以 Mathworks 文章中的示例类为例。我做了小测试脚本:

clear all
clc
n = 1e5;
%% OOP way - abysimal
result = zeros(1, n);
tic
for i = 1:n
    cyl = SimpleCylinder();
    cyl.R = i;
    cyl.Height = 10;
    result(i) = cyl.volume();
end
toc
%% OOP Vectorized - fair
clear result
tic
cyl = SimpleCylinder();
cyl.R = 1:n;
cyl.Height = 10;
result = cyl.volume();
toc
%% for loop without objects - good
result = zeros(1, n);
tic
for i = 1:n
    result(i) = pi .* i.^2 .* 10;
end
toc
%% Vectorized without objects - excellent
clear result
tic
R = 1:n;
result = pi .* R.^2 .* 10;
toc

有了这些结果:

Elapsed time is 6.141445 seconds.
Elapsed time is 0.006245 seconds.
Elapsed time is 0.002116 seconds.
Elapsed time is 0.000478 seconds.

如您所见,每个属性访问都在减慢。尝试向量化(一如既往),但即使是简单的 for 循环也优于小 n 的向量化 OOP 解决方案。(在我的电脑上,他们在 1e7 时收支平衡)

基本信息:Matlab 中的 OOP 很慢!您为每次访问财产付出代价。


对你的问题:当你打电话时

myfun2 (inputvar.var1, inputvar.var2, ... etc )

值被复制。在函数中,您不再处理类。访问变量很快。但是,如果您通过整个类,则每次访问属性都很慢。您可以通过在局部变量中缓存所有属性并使用它们来规避这种情况。


如果您修改类以从句柄继承,一切都会变得更快,但差异可以忽略不计。

于 2013-07-29T20:03:05.470 回答