我试图在我的 Delphi 应用程序中充分发挥性能,现在我找到了一个使用动态数组的过程。其中最慢的一行是
SetLength(结果, Len);
用于初始化动态数组。当我查看 SetLength 过程的代码时,我发现它远非最佳。调用顺序如下:
_DynArraySetLength -> DynArraySetLength
DynArraySetLength 获取数组长度(初始化时为零),然后使用 ReallocMem,这对于初始化也是不必要的。
我一直在用 SetLength 来初始化动态数组。也许我错过了什么?有没有更快的方法来做到这一点?
编辑:描述主要算法会占用大量空间,而且确实没有必要,因为它试图优化其中的一小部分。一般来说,它是车辆路径问题( http://en.wikipedia.org/wiki/Vehicle_routing_problem )的变体。我确实需要无数的分配,因为我必须保留所有数据,并单独保存。如果我能在这里想到一些聪明的数据结构,可能会有所帮助,但我能想到的任何东西都会大大增加代码的复杂性。 基本上我已经在算法层面上做了我能做的一切,所以现在我试图从低级的事情中得到我能做的一切。所以这是一个相当狭隘的问题:是否有可能增加这个特定的调用。我认为要做到这一点,我需要根据 SetLength 代码编写自己的初始化函数。并使其内联。
最佳答案
这更像是一条评论,但由于在评论中发布大块代码并不美观,所以我将其发布在这里。
有时,如果您不知道最终会得到多少个元素,可能会很想编写如下代码:
var
Arr: array of cardinal;
procedure AddElement(const NewElement: cardinal);
begin
SetLength(Arr, length(Arr) + 1);
Arr[high(Arr)] := NewElement;
end;
这非常糟糕,因为每次添加新元素时都需要重新分配内存。更好的方法(如果可能的话)是找到元素数量的上限,例如 MAX_ELEMENTS = 100000;然后初始设置长度:
SetLength(Arr, MAX_ELEMENTS);
然后创建一个变量,例如
var
ActualNumberOfElements: cardinal = 0;
并写
procedure AddElement(const NewElement: cardinal);
begin
Arr[ActualNumberOfElements] := NewElement;
inc(ActualNumberOfElements);
end;
填充完数组后,只需截断它即可:
SetLength(Arr, ActualNumberOfElements);
关于performance - 在 Delphi 中初始化数组的更快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2817430/