在我看来,当在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使用以下脚本创建这些简单对象的1x10.000数组的根据我的计算机上的分析器0,4秒:
for n=10000:-1:1 % counting backwards for Memory pre-allocation
ObjectList(n)=SomeSimpleObject();
end然而,在类构造函数中执行相同的操作,并将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为了寻找答案,我遇到了一个关于Matlab内存分配和garbage collection的讨论。Mikhail的回答(也与我的问题没有直接关系)使我认为这可能是Matlab实现对象的方式中的一个根本问题,但我仍然不确定。
发布于 2011-10-12 08:48:29
受@Jonas Heidelberg和@Tobias Heß的启发,我提出了以下解决方案,它根本不需要单元格数组。对象存储在一个辅助数组中,一旦完成,它们将被复制到属性数组中:
带有数组“后置分配”的 HostingObject代码:
classdef JacobHostingObject < handle
% This Objects Hosts a List of Objects that are created in the constructor
properties
ObjectList=SomeSimpleObject
end
methods
function obj=JacobHostingObject()
for n=10000:-1:1 % counting backwards for Memory pre-allocation
a(n)=SomeSimpleObject(); % auxiliary array for "post-allocation"
end
obj.ObjectList=a; % "post-allocation"
end
end
end那么这三种解决方案(乔纳斯、托拜厄斯和我的)是如何执行的呢?
我运行了一些测试(使用MATLAB R2011b 64位)来比较它们:
10.000件物体
运行时间:Tobias:0,30秒;:0,31秒;Jonas:2,02秒;原始:56,79秒
100.000件物体
运行时间:Tobias:2,42秒;雅各布:2,95秒;Jonas:203,03秒
1.000.000对象
运行时间:Tobias:23,84秒;雅各布:29,18秒
所以看起来Tobias版本是最快的解决方案
有趣的是,Jonas的解决方案比原来的要好得多,但是与其他两种解决方案相比,比例要差得多。这证实了我在先前的问题"slow performance when storing handle objects in a cell array"中所作的观察。具有讽刺意味的是,使用导致我早期问题的技术却是对这个问题的改进。然而,Tobias解决方案甚至也回答了我以前的问题(我会在那里发布一个参考)。
然而,仍然不清楚在MATLAB内部到底发生了什么,从而导致了性能的差异。这可能有助于了解这一点,以避免遇到类似的问题在未来!
发布于 2011-10-11 14:17:06
我不知道为什么您的代码速度慢,但是我找到了一种修复的方法:使用单元格数组而不是普通数组。我不认为它是完全直观的,但下面是我的分析结果:
>> tic,a=HostingObject;toc
Elapsed time is 105.320128 seconds.
>> tic,a=JonasHostingObject;toc
Elapsed time is 2.394570 seconds.该对象的定义如下:
classdef JonasHostingObject < handle
properties
ObjectList
end
methods
function obj=JonasHostingObject()
obj.ObjectList=cell(10000,1);
for n=1:10000
obj.ObjectList{n}=SomeSimpleObject();
end
end
end
end我正在使用MATLAB R2011a 64位,以防有关系。
发布于 2011-10-11 16:07:08
我找到了另一个答案。我认为使用单元格数组不是一个好的解决方案,因为您对对象的访问与数组中的访问权限不同。但是您可以使用一个单元格来解决这个问题:
classdef HostingObject < handle
% This Objects Hosts a List of Objects that are created in the
% constructor
properties
ObjectList=SomeSimpleObject
end
methods
function obj=HostingObject()
% Creating first a cell array
helpCell = cell(10000,1);
for n=1:10000
helpCell{n}=SomeSimpleObject();
end
% Convert the cell array to the object array
obj.ObjectList = horzcat(helpCell{:});
end
end
endhttps://stackoverflow.com/questions/7726487
复制相似问题