我正在尝试使用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)
整体运行时间已减半。
谢谢!
答案 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”。
我承认使用标量对象会使你的代码不那么直观,但这是一个权衡,你必须权衡。