首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免Matlab在创建句柄对象数组作为对象属性时使用指数时间

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

Stack Overflow用户
提问于 2011-10-11 13:05:10
回答 3查看 3.3K关注 0票数 9

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

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

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

简单对象的代码:

代码语言:javascript
复制
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秒:

代码语言:javascript
复制
for n=10000:-1:1 % counting backwards for Memory pre-allocation
    ObjectList(n)=SomeSimpleObject();
end

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

代码语言:javascript
复制
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实现对象的方式中的一个根本问题,但我仍然不确定。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-12 08:48:29

@Jonas Heidelberg@Tobias Heß的启发,我提出了以下解决方案,它根本不需要单元格数组。对象存储在一个辅助数组中,一旦完成,它们将被复制到属性数组中:

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

代码语言:javascript
复制
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内部到底发生了什么,从而导致了性能的差异。这可能有助于了解这一点,以避免遇到类似的问题在未来!

票数 4
EN

Stack Overflow用户

发布于 2011-10-11 14:17:06

我不知道为什么您的代码速度慢,但是我找到了一种修复的方法:使用单元格数组而不是普通数组。我不认为它是完全直观的,但下面是我的分析结果:

代码语言:javascript
复制
>> tic,a=HostingObject;toc
Elapsed time is 105.320128 seconds.

>> tic,a=JonasHostingObject;toc
Elapsed time is 2.394570 seconds.

该对象的定义如下:

代码语言:javascript
复制
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位,以防有关系。

票数 4
EN

Stack Overflow用户

发布于 2011-10-11 16:07:08

我找到了另一个答案。我认为使用单元格数组不是一个好的解决方案,因为您对对象的访问与数组中的访问权限不同。但是您可以使用一个单元格来解决这个问题:

代码语言:javascript
复制
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

end
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7726487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档