【问题标题】:MATLAB OOP and Slow Operator OverloadingMATLAB OOP 和慢速运算符重载
【发布时间】:2013-01-13 17:37:12
【问题描述】:

是否有可能从以下简单类中获得 3-6 倍的加速?

我正在尝试创建一个伪装成内联函数的类,但括号/subsref 运算符重载对我来说不够快。

我创建了类 CTestOp 来替换内联函数 f = @(x) A*x,方法是让 subsref 获取一个向量并将其与类属性 A 相乘。

基准测试表明,对于小尺寸 Ax(例如,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


【解决方案1】:

如果您想在 Matlab 中编写快速代码,诀窍始终是对代码进行矢量化处理。 使用 Matlab OO 也是如此。虽然我目前无法对其进行测试,但我非常有信心您可以通过执行一项大操作而不是许多小操作来减少开销。

在您的具体示例中,您可以再次运行基准测试,并通过更改这两行来查看我的陈述是否真的成立:

m = 500; % Work with one big matrix rather than many tiny ones

nc = 99; % Just some number that should give you reasonable run times

【讨论】:

  • 在这种情况下,我选择了一个小维度来隔离和测量开销。的确,我们可以减少花费在开销上的 percent 时间,但希望是消除实际开销,而不是仅仅说它无关紧要。
  • @Steve 是正确的,但是如果你的大矩阵包含所有这些小矩阵的信息,那么也可以减少以毫秒为单位的总开销。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 2018-11-30
  • 1970-01-01
相关资源
最近更新 更多