在创建句柄对象数组作为对象属性时,如何避免Matlab采用指数时间

Jac*_*cob 9 arrays oop matlab memory-management properties

在我看来,当在Matlab中创建一个简单的句柄对象数组时,它就是线性的.但是,如果我创建完全相同的数组并将其存储为对象的属性,则时间会呈指数级增长 - 因此在创建许多对象时程序会变得非常慢.

我的问题是为什么会发生这种情况以及如何避免这种情况? 对象属性的预分配是否在我的代码中没有正确实现,或者Matlab处理这些事情的方式是否存在根本问题?

我写了一个简单的测试来说明这个问题:

简单对象代码:

classdef SomeSimpleObject < handle
% SomeSimpleObject defines an Object that has one property

properties
    property=0;
end

methods
    function SimpleObj=SomeSimpleObject()
        if nargin~=0
            SimpleObj.property=1;
        end
    end
end

end
Run Code Online (Sandbox Code Playgroud)

使用以下脚本创建1x10.000这些简单对象的数组根据我的机器上的分析器0,4秒:

for n=10000:-1:1 % counting backwards for Memory pre-allocation
    ObjectList(n)=SomeSimpleObject();
end
Run Code Online (Sandbox Code Playgroud)

然而,在类构造函数中执行相同的操作并将10.000个对象的数组存储为属性需要59秒,并且它会更快地变得更糟.通过从这个类创建一个对象来尝试它(例如a = HostingObject)

classdef HostingObject < handle
% This Objects Hosts a List of Objects that are created in the
% constructor

properties
    ObjectList=SomeSimpleObject
end

methods
    function obj=HostingObject()    
        for n=10000:-1:1 % counting backwards for Memory pre-allocation
            obj.ObjectList(n)=SomeSimpleObject();
        end
    end
end

end
Run Code Online (Sandbox Code Playgroud)

寻找答案我遇到了关于Matlab内存分配和垃圾收集的讨论.Mikhail的答案(也与我的问题没有直接关系)让我觉得它可能是Matlab实现对象的方式的一个基本问题,但我仍然不确定.

Jac*_*cob 4

受到@Jonas Heidelberg@Tobias He\xc3\x9f答案的启发,我提出了以下根本不需要单元数组的解决方案。这些对象存储在辅助数组中,一旦完成,它们就会被复制到属性数组中:

\n\n

具有数组“分配后”的 HostingObject 代码:

\n\n
classdef JacobHostingObject < handle\n% This Objects Hosts a List of Objects that are created in the constructor\n\nproperties\n    ObjectList=SomeSimpleObject\nend\n\nmethods\n    function obj=JacobHostingObject()         \n        for n=10000:-1:1 % counting backwards for Memory pre-allocation         \n            a(n)=SomeSimpleObject(); % auxiliary array for "post-allocation"           \n        end            \n         obj.ObjectList=a; % "post-allocation"\n    end\nend\n\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

那么这三个解决方案(Jonas、Tobias 和我的)表现如何?

\n\n

我运行了一些测试(使用 MATLAB R2011b 64 位)来比较它们:

\n\n

10.000 个对象

\n\n

经过时间: 托比亚斯:0,30 秒;雅各布:0,31 秒;乔纳斯:2,02 秒;原版:56,79 秒

\n\n

100.000 个对象

\n\n

经过时间: 托比亚斯:2,42 秒;雅各布:2,95 秒;乔纳斯:203,03 秒

\n\n

1.000.000 个对象

\n\n

经过时间:托比亚斯:23,84 秒;雅各布:29,18 秒

\n\n

所以看起来托比亚斯版本是最快的解决方案

\n\n

有趣的是,乔纳斯的解决方案比原来的解决方案要好得多,但扩展性比其他两个解决方案差得多。这证实了我在之前的问题“在元胞数组中存储句柄对象时性能缓慢”中所做的观察。有点讽刺的是,使用导致我之前问题的技术却是对这个问题的改进。然而,托比亚斯的解决方案甚至也回答了我的老问题(我将在那里发布参考文献)。

\n\n

然而,目前尚不清楚 MATLAB 内部究竟发生了什么原因导致了性能差异。了解这一点可能会有所帮助,以避免将来遇到类似的问题!

\n