我有一个例程,将例程元素(“ 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的内置内存管理器相比,分配和重新分配内存要好得多。