在MATLAB中非常慢的对象数组操作

时间:2012-02-02 09:02:51

标签: performance oop matlab

我正在尝试使用matlab中的OOP使用曼哈顿启发式实现8个益智程序,每个节点由对象“状态”表示。但是,我已经失去了为队列实现对象数组的速度问题。经过大量的试验和错误,这是我能做的最快的事情(我讨厌使用全局对象,但似乎任何尝试传递数组或使用对象的速度都会大大减慢它):

.classdef state < handle    
.    properties
.        position; %3x3 array
.        moves;  
.        blank;
.        parent;
.        prevmove;
.        mdist;
.   end

...


队列已预先分配

queue = repmat(state,1,5000);


.function newfront = q(item,front)

.global queue;
.if isempty(front)
.    newfront = 1;
.    queue(1) = item;
.else
.    for i = front:-1:0
.        if i == 0
.            break;
.        end
.        a = item.mdist;        
.        b = queue(i).mdist;
.        if (a < b)
.            break;
.        else
.            queue(i+1) = queue(i);
.        end    
.    end
.    newfront = front + 1;
.    queue(i+1) = item;
.end
.end

使用MATLAB探查器:

eightpuzzle                     1       67.941 s    2.550 s 
eightpuzzle>q                   4722    59.657 s    59.657 s    
....
118 queue(i+1) = queue(i);     2583916  29.064 s    48.7%   
120 end                        2583916  16.202 s    27.2%   
114 b = queue(i).mdist;        2587318  4.357 s     7.3%    
113 a = item.mdist;            2587318  2.783 s     4.7%    
115 if (a < b)                 2587318  2.721 s     4.6%

无论如何都要让它跑得更快?有趣的是要注意使用

a = item.mdist;        
b = queue(i).mdist;
if (a < b)
...

而不是

if (item.mdist < queue(i).mdist)

整体运行时间已减半。

谢谢!

2 个答案:

答案 0 :(得分:1)

我不知道它是否与MATLAB中关于一般OOP慢度的这个主题有关: Is MATLAB OOP slow or am I doing something wrong?

这是关于句柄类行为缓慢的另一个链接,但是自从多年前报告错误以来,它可能已经修复了: http://www.mathworks.com/matlabcentral/newsreader/view_thread/288746

答案 1 :(得分:1)

在MATLAB中使用对象数组时会产生大量内存开销,就像在结构数组中一样。每个数组元素的每个字段都是它自己的mxArray,这会增加大量的内存开销。考虑使用带有非标量字段的1x1结构,而不是带有标量字段的1xN结构 - 它在内存中会大大减少,并且对每个字段的访问速度会快得多。

一个例子:

具有两个标量字段“a”和“b”的1x100结构数组在内存中需要(100 * 2)+ 1 mxArray对象。

1x1结构数组包含两个非标量字段“a”和“b”,每个字段大小为1x100,内存中需要3个mxArray对象。

您的对象数组与结构数组非常相似,其中每个数组元素的字段可以被视为指针。假设您有一个对象数组“obj”,它是1xN,字段为“a”和“b”。引用Kth对象字段的“a”:

OBJ(K).A

这是一个索引操作,也是一个mxArray指针取消引用字段“a”。

我承认使用标量对象会使你的代码不那么直观,但这是一个权衡,你必须权衡。