我有一个例程,将例程元素(“ 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中使用“查找错误”工具时,它将带我进入CPU窗口中的@DynArrayAsg方法。但是我从来没有得到Delphi帮助说的EOutOfMemory异常,如果没有足够的内存来重新分配变量,我会得到。

这会减慢对内存的预期行为吗?我正在使用Delphi 6。

最佳答案

是的,因为当您重新分配它时,如果没有足够的连续空间仅在现有数组的末尾添加一个元素,则它必须找到另一个足够大的块,进行分配,复制整个现有数组,然后重新分配原版的。阵列越大,副本越长。

TList通过以2的幂数分配其内部数组,而不是“恰好满足我的需要”,然后使用Count变量标记实际使用的上限,从而帮助缓解了此问题。也许您可以做类似的事情?

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

10-05 22:40