Arrays – Decrease performance when you store handle objects in unit arrays

I only have a small part of MATLAB code that has a lot of performance issues, I hope you can learn how to improve it:

I am developing an agent-based Simulation, it creates many handle objects. Some of them are agents, others can be objects owned by agents, for example.

In order to clearly identify each handle object, each handle object is obtained by ” The unique Id (obj.Id) issued by the “IdDistributor” object. The IdDistributor itself is handed over to the constructor of each object whose Id is to be retransmitted, and called from there to give the Id-number (giveId).

In addition, IdDistributor also keeps a kind of phone book (IdRegistry), which associates each Id with an object. Therefore, given the Id, the object can be found in the IdRegistry.

I did this by using a cell Array to achieve this, the array array stores different handle objects in the fields matching their Id. (Normal arrays don’t work because the objects belong to different classes).

Testing my simulation is very Slow, MATLAB Profiler shows that 99% of the time is spent on IdDistributor, especially the rows that store objects in the IdRegistry (when I try to create about 10,000, it takes 1 second for each object).

Now I want to try a similar solution that takes less time. As you can see in the code below, I have tried to increase the speed by pre-allocation (when it is full, I extend the IdRegistry 10,000 units instead of incrementing one by one 1). I also thought about trying somehow to get the MATLAB internal Id of the handle object when I read that the Id is not permanent and can be changed by the system but did not follow that path.

I really appreciate any ideas how to speed up the code or find a solution/improve my concept!

Here my code:

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

By the way. Change it For IdDist.IdRegistry {IdNumber} = obj; not much help

classdef IdDistributor 
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< br /> 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

Since you did not delete the object from the registry, you may want to try it from matlab.mixin. The Heterogeneous class derives all objects and stores them as regular arrays. Please note that this will require R2011a or newer.

I don’t know if this is faster, but it’s worth trying. Of course, it will only be useful when IdDistributor generates all IDs, because they are sequential.

In addition, my tests show that

length(IdDist.IdRegistry )

It’s also very slow, so you can also store the length of the registry in IdDistributor. For safety, I recommend setting SetAccess as a protected attribute.

I only have a small part of MATLAB code that has a lot of performance problems, I hope you can learn how to improve it:

I am developing an agent-based simulation in MATLAB, and it creates many Handle objects. Some of them are agents, others can be, for example, objects owned by agents.

In order to clearly identify each handle object, each handle object is uniquely issued by the “IdDistributor” object Id(obj.Id). IdDistributor itself is handed over to the constructor of each object whose Id is to be retransmitted, and called from there to give Id-number(giveId).

In addition, IdDistributor also retains A kind of phone book (IdRegistry), which associates each Id with an object. Therefore, given the Id, the object can be found in the IdRegistry.

I achieved this by using a cell array, This array of arrays stores different handle objects in the fields matching their Id. (Normal arrays do not work because the objects belong to different classes).

Testing my simulation is very slow, MATLAB Prof iler shows that 99% of the time is spent on IdDistributor, especially the rows that store objects in the IdRegistry (when I try to create about 10,000, it takes 1 second for each object).

Now I Want to try a similar solution and spend less time. As you can see in the code below, I have tried to increase the speed by pre-allocation (when it is full, I expand the IdRegistry by 10,000 units , Instead of increasing 1) one by one. I also thought about trying somehow to get the MATLAB internal Id of the handle object when I read that the Id is not permanent and can be changed by the system but did not follow that path.

I really appreciate any ideas how to speed up the code or find a solution/improve my concept!

Here my code:

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

By the way. Change it For IdDist.IdRegistry {IdNumber} = obj; not much help

classdef IdDistributor 
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< br /> if IdNumber>=length(IdDist.IdRegistry) %Extend the Register by 10000
IdDist.IdRegistry(IdNumber+10000)={[]};
en d
if IdNumber >0
IdDist.IdRegistry(IdNumber)={obj};
end
end %function
end %methods
end %class

Since you did not delete the objects from the registry, you might want to try to derive all objects from the matlab.mixin.Heterogeneous class and then store them as regular Array. Please note that this will require R2011a or newer.

I don’t know if this is faster, but it’s worth trying. Of course, it’s only useful if IdDistributor generates all IDs, Because they are sequential.

In addition, my test shows that

length(IdDist.IdRegistry)

is also very slow, So you can also store the length of the registry in IdDistributor. For security, I recommend setting SetAccess as a protected attribute.

Leave a Comment

Your email address will not be published.