Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slow performance when storing handle objects in a cell array

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
like image 693
Jacob Avatar asked Oct 06 '11 14:10

Jacob


People also ask

Are Matlab cell arrays slow?

I've found that the performance of cell Arrays, multi-dimensional arrays, and structure arrays are all far slower than the use of multiple independent variables. Thus, my optimized codes have been using super long if-statements and functions which completely write out which variables are needed or not.

What is a cell array in Matlab?

A cell array is a data type with indexed data containers called cells, where each cell can contain any type of data. Cell arrays commonly contain either lists of text, combinations of text and numbers, or numeric arrays of different sizes.


1 Answers

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.

like image 137
Nzbuu Avatar answered Oct 27 '22 00:10

Nzbuu