大型动态阵列 - 慢速写入

时间:2009-11-23 15:52:47

标签: delphi

我有一个例程,它将序数元素(“Day”或“Night”枚举类型)添加到多维动态数组中,该数组声明为:

TShiftType = (stDay, stNight);
TScheduleArray =  array of array of array [1..DaysPerWeek] of TShiftType;

数组可以包含1个元素(例如(Day, Day, Day, Day, Day, Night, Night))和20,000个元素之间的任何内容。每个元素本身可以具有子元素,这取决于正在处理的周数。

因此,两周数组中的一个元素可能如下所示:

((stDay, stDay, stDay, stDay, stDay, stNight, stNight), (stDay, stDay, stDay, stDay, stDay, stNight, stNight))

当元素数量相对较低(大约低于1000)时,这种方法运行得非常快并且效果非常好。一旦周数和元素增加,只需向数组添加一个新元素(在调用SetLength之后将数组的长度增加一个)开始以指数方式减慢。

有时我也会收到访问冲突。当我在Delphi中使用“Find Error”工具时,它会转到CPU窗口中的@DynArrayAsg方法。但是,如果没有足够的内存可用于重新分配变量,那么我永远不会得到Delphi帮助说的EOutOfMemory异常。

这是否会降低对内存预期行为的访问速度?我正在使用Delphi 6。

1 个答案:

答案 0 :(得分:7)

是的,因为当你重新分配它时,如果没有足够的连续空间只在现有数组的末尾添加一个元素,它必须找到另一个足够大的块,分配它,复制整个现有数组,以及然后解除分配原件。数组越大,副本就越长。

TList通过以两种大小的大小分配其内部数组来帮助缓解这个问题,而不是“完全按照我需要的那么大”,然后使用Count变量来标记实际使用的内容的上限。也许你可以做类似的事情?

此外,如果您还没有,请获取FastMM。与Delphi 6的内置内存管理器相比,它在分配和重新分配内存方面要好得多。