Slow performance when storing handle objects in a

2019-06-20 08:41发布

I have massive performance problems with just a very little portion of my MATLAB Code an hope you might have an idea how to improve it:

I am developing an agent based simulation in MATLAB that creates lots of handle objects. Some of them are agents others can be e.g. objects that are owned by the agents.

To clearly identify each of these handle object every single one gets a unique Id (obj.Id) that is issued by an "IdDistributor" object. The IdDistributor itself is handed over to the constructor of each object that is to resive an Id and is called from there to give out an Id-number (giveId).

In addition the IdDistributor keeps a sort of phone book (an IdRegistry) that associates each Id with the object. So given the Id one can look up the object in the IdRegistry.

I implemented this by using a cell array that stores the different handle objects in exactly that field that matches their Id. (Normal array does not work since the objects are of different classes).

Testing my simulation it is really slow and the MATLAB Profiler shows that 99% of the time is spent with the IdDistributor especially with the line that stores the objects in the IdRegistry (It took something like 1 seconds per object when I tried to create about 10,000 objects).

Now I'm trying to come to a similar solution that takes less time. As you can see in the code below I have already tried to increase Speed with pre-allocation (I extend the IdRegistry by 10,000 cells when it is full, instead of sizing up 1 by 1).I also thought about trying to somehow get the MATLAB internal Id of the handle objects but didn't follow that road when I read that that Id is not permanent and can be changed by the system.

I would really much appreciate any ideas either how to speed up the code or to find a workaround/improvement to my concept!

Here my Code:

The slowest line is IdDist.IdRegistry(IdNumber)={obj};

btw. changing it to IdDist.IdRegistry{IdNumber}=obj; didn't help much

classdef IdDistributor < handle

properties
    Id=int64(1); %Her own ID
    LastId=int64(1);
    IdRegistry={}
end

methods
    function IdDist=IdDistributor()
        IdDist.Id=int64(1);
        IdDist.LastId=int64(1);
        IdDist.register(IdDist);
    end
    function IdNum=giveId(IdDist,obj)
        IdNum=IdDist.LastId+int64(1);
        IdDist.LastId=IdNum;
        IdDist.register(obj,IdNum)
    end
    function register(IdDist,obj,IdNum)
        if nargin==2      
            IdNumber=obj.Id;
        elseif nargin==3
            IdNumber=IdNum;
        end
            if IdNumber>=length(IdDist.IdRegistry) %Extend the Register by 10000
              IdDist.IdRegistry(IdNumber+10000)={[]};    
            end
            if IdNumber >0
              IdDist.IdRegistry(IdNumber)={obj};
            end
    end %function
    end %methods
    end %class

2条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-06-20 09:27

I have further looked into the issue and it appears to me that actually most time is lost in the process of calling the giveId method of the IdDistributer from a different object and not so much inside the method.

I have also identified other places in my program where similar problems occur. Especially when many handle objects are constructed and stored in an array and this array is stored as the property of an object. So the original cause of the slow performance might lie in this as the IdDistributer is usually used when new handle objects are created.

Since this is a somewhat different topic I posted another question including some simple code for illustration.

查看更多
再贱就再见
3楼-- · 2019-06-20 09:29

Since you're not deleting objects from your registry, you might like to try deriving all your objects from the matlab.mixin.Heterogeneous class, then storing them as a regular array. Note that this will require R2011a or newer.

I don't know if this is faster, but it's something to try. Of course it'll only be useful if all your IDs are generated by the IdDistributor, since they're sequential.

Also, my tests suggest that

length(IdDist.IdRegistry)

is also slow, so you could store the length of the registry in the IdDistributor as well. and I would suggest setting the SetAccess to protected for the properties, for safety.

查看更多
登录 后发表回答