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实现对象的方式的一个基本问题,但我仍然不确定.
受到@Jonas Heidelberg和@Tobias He\xc3\x9f答案的启发,我提出了以下根本不需要单元数组的解决方案。这些对象存储在辅助数组中,一旦完成,它们就会被复制到属性数组中:
\n\n具有数组“分配后”的 HostingObject 代码:
\n\nclassdef 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\nRun Code Online (Sandbox Code Playgroud)\n\n那么这三个解决方案(Jonas、Tobias 和我的)表现如何?
\n\n我运行了一些测试(使用 MATLAB R2011b 64 位)来比较它们:
\n\n10.000 个对象
\n\n经过时间: 托比亚斯:0,30 秒;雅各布:0,31 秒;乔纳斯:2,02 秒;原版:56,79 秒
\n\n100.000 个对象
\n\n经过时间: 托比亚斯:2,42 秒;雅各布:2,95 秒;乔纳斯:203,03 秒
\n\n1.000.000 个对象
\n\n经过时间:托比亚斯:23,84 秒;雅各布:29,18 秒
\n\n所以看起来托比亚斯版本是最快的解决方案
\n\n有趣的是,乔纳斯的解决方案比原来的解决方案要好得多,但扩展性比其他两个解决方案差得多。这证实了我在之前的问题“在元胞数组中存储句柄对象时性能缓慢”中所做的观察。有点讽刺的是,使用导致我之前问题的技术却是对这个问题的改进。然而,托比亚斯的解决方案甚至也回答了我的老问题(我将在那里发布参考文献)。
\n\n然而,目前尚不清楚 MATLAB 内部究竟发生了什么原因导致了性能差异。了解这一点可能会有所帮助,以避免将来遇到类似的问题!
\n