【发布时间】:2011-12-02 08:00:34
【问题描述】:
我的 MATLAB 代码的一小部分存在大量性能问题,希望您能知道如何改进它:
我正在 MATLAB 中开发一个基于代理的模拟,以创建 大量的句柄对象。其中一些是代理,其他可以是例如代理拥有的对象。
为了清楚地识别这些句柄对象中的每一个每一个都有一个唯一的 ID (obj.Id),它由“IdDistributor”对象发出。 IdDistributor 本身被移交给每个对象的构造函数,该构造函数将重新生成一个 Id,并从那里调用以给出一个 Id 编号 (giveId)。
此外,IdDistributor 保留了一种电话簿(IdRegistry),将每个 Id 与对象相关联。因此,给定 Id,可以在 IdRegistry 中查找对象。
我通过使用一个单元数组来实现这一点,该数组将不同的句柄对象存储在与其 Id 完全匹配的字段中。 (普通数组不起作用,因为对象属于不同的类)。
测试我的模拟真的很慢,MATLAB Profiler 显示 99% 的时间都花在了 IdDistributor 上,尤其是在将对象存储在IdRegistry(当我尝试创建大约 10,000 个对象时,每个对象大约需要 1 秒)。
现在我正试图找到一个类似的耗时更少的解决方案。正如您在下面的代码中看到的那样,我已经尝试通过预分配来提高速度(当 IdRegistry 已满时,我将其扩展了 10,000 个单元,而不是按 1 比 1 调整大小)。我还想过尝试以某种方式获取句柄对象的 MATLAB 内部 Id,但当我读到该 Id 不是永久性的并且可以由系统更改时并没有遵循这条路。
我非常感谢任何想法,无论是如何加快代码速度或找到解决方法/改进我的概念!
这是我的代码:
最慢的一行是IdDist.IdRegistry(IdNumber)={obj};
顺便说一句。将其更改为 IdDist.IdRegistry{IdNumber}=obj; 并没有太大帮助
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
【问题讨论】:
-
我现在尝试将预分配改为:IdDist.IdRegistry(IdNumber+10000)={SomeDummyHandleObject}; 因为有朋友建议单元格的大小可能会从空单元格 {[]} 更改为存储句柄对象引用的时间,并可能导致 Matlab 重新分配内存。但是,这在 IdDistributor.register 中的 1.428 秒自拍时间中仅节省了 0.009 秒。
-
运行“慢”时内存消耗如何?您是否可以制作对象的副本而不仅仅是存储句柄?
-
因为它们都是 Matlab 句柄对象,如果它们被/可以被复制,我会感到惊讶。然而,我刚刚通过将 IdRegistry 的类型从 Cell 更改为 Map 进行了重大改进。我只是要发布我的解决方案,但由于我是新手,stackoverflow 迫使我等待 8 小时。简而言之:属性部分的更改: IdRegistry=containers.Map('KeyType','int64','ValueType','any') ;取出预分配块;注册更改为:IdDist.IdRegistry(IdNumber)=obj; ;现在只需要 17% 的时间。不知道为什么。几个小时后得到完整答案。
-
即使它们是句柄对象(并且 imo 不应该被复制),我尝试检查内存但发现很难做到,因为对象是在注册时创建的(其中是他们建设的一部分)。
-
昨天我以为我设法使用 Map 将代码加速了 5 倍(使用 400 个对象进行了测试) - 我使用 10.000 个对象进行了测试一夜之间,它并不比原来的细胞快。于是我又疑惑了。如果我发现新的东西,我会通知您,并感谢您提供任何进一步的建议。
标签: arrays performance oop matlab