【发布时间】:2013-01-13 17:37:12
【问题描述】:
是否有可能从以下简单类中获得 3-6 倍的加速?
我正在尝试创建一个伪装成内联函数的类,但括号/subsref 运算符重载对我来说不够快。
我创建了类 CTestOp 来替换内联函数 f = @(x) A*x,方法是让 subsref 获取一个向量并将其与类属性 A 相乘。
基准测试表明,对于小尺寸 A 和 x(例如,m=5),使用内联函数的时间是编写 A*x 的 4-7 倍,而它需要 4-7 倍的时间使用类作为使用内联函数:
Elapsed time is 0.327328 seconds for the class
Elapsed time is 0.053322 seconds for the inline function.
Elapsed time is 0.011704 seconds for just writing A*x.
我已经进行了一系列改进才能到达这里,但存在一些问题。例如,通过不要求this.A,我可以看到可观的收益,但这违背了整个目的。我本来希望使用一个允许我们编写各种 operation 函数的抽象类——但是,虽然使类抽象并没有增加太多时间,但进行实际的函数调用却可以。
有什么想法吗?
班级是:
classdef CTestOp < handle
properties
A = [];
end
methods
function this = CTestOp(A)
this.A = A;
end
function result = operation(this, x)
result = this.A*x;
end
function result = subsref(this, S)
% switch S.type
% case '()'
% result = this.operation(S.subs{1}); % Killed because this was really slow
% result = operation(this, S.subs{1}); % I wanted this, but it was too slow
result = this.A*S.subs{1};
% otherwise
% result = builtin('subsref', this, S);
% end
end
end
end
而测试代码是:
m = 5;
A = randn(m,m);
x = randn(m,1);
f = @(x) A*x;
myOp = CTestOp(A);
nc = 10000;
% Try with the class:
tic
for ind = 1:nc
r_abs = myOp(x);
end
toc
% Try with the inline function:
tic
for ind = 1:nc
r_fp = f(x);
end
toc
% Try just inline. so fast!
tic
for ind = 1:nc
r_inline = A*x;
end
toc
【问题讨论】:
-
我确信性能和 OO 在 matlab 中是相互排斥的
-
如果您还没有这样做,请查看这篇文章blogs.mathworks.com/loren/2012/03/26/…。
-
@slayton:使用 OOP 就像使用 Matlab 的其余部分一样:避免大量不必要的函数/方法调用。像在 Java 或 C++ 中那样在 Matlab 中进行 OOP(即,许多类具有许多相互调用的小方法)效率不高。
-
@Navan 是完全正确的 - 特别是请注意,您正在使用比函数调用样式调用慢的点引用方法调用。 (即您使用的是 obj.method() 而不是 method(obj) - 在内部,对于第一种样式,MATLAB 首先必须检查您是否要索引 obj 而不是在其上调用函数(是的,即使您放那里的括号))。
标签: oop matlab optimization