【发布时间】:2017-08-20 19:13:15
【问题描述】:
我正在比较这两种初始化动态数组的方法的性能:
Arr := TArray<integer>.Create(1, 2, 3, 4, 5);
和
SetLength(Arr, 5);
Arr[0] := 1;
Arr[1] := 2;
Arr[2] := 3;
Arr[3] := 4;
Arr[4] := 5;
我准备了一个测试,我注意到使用数组“构造函数”需要的时间是其他方法的两倍。
测试:
uses
DateUtils;
function CreateUsingSetLength() : TArray<integer>;
begin
SetLength(Result, 5);
Result[0] := 1;
Result[1] := 2;
Result[2] := 3;
Result[3] := 4;
Result[4] := 5;
end;
...
const
C_COUNT = 10000000;
var
Start : TDateTime;
i : integer;
Arr : TArray<integer>;
MS1 : integer;
MS2 : integer;
begin
Start := Now;
i := 0;
while(i < C_COUNT) do
begin
Arr := TArray<integer>.Create(1, 2, 3, 4, 5);
Inc(i);
end;
MS1 := MillisecondsBetween(Now, Start);
Start := Now;
i := 0;
while(i < C_COUNT) do
begin
Arr := CreateUsingSetLength();
Inc(i);
end;
MS2 := MillisecondsBetween(Now, Start);
ShowMessage('Constructor = ' + IntToStr(MS1) + sLineBreak + 'Other method = ' + IntToStr(MS2));
在我的机器上测试,结果值总是接近以下:
构造函数 = 622
其他方法 = 288
为什么数组“构造函数”这么慢?
【问题讨论】:
-
这很容易通过查看生成的代码来检查。我希望你有优化,没有范围检查等。
-
@Deltics 在您删除的答案中,您评论道:有趣的是,它既“完全等效”又慢。即使它实际上不是一个类,它显然也不完全等价。 :shrug: Rudy 说这些类型是完全等价的。他们是。不同的是为初始化相同类型的变量而生成的代码。您似乎仍然没有理解被比较的两个事物在同一类型
TArray<Integer>上运行。我想知道,你有支持泛型的 Delphi 版本吗? -
您显示的代码肯定不是产生这些不同结果的代码。这只发生在直接在循环体中修改
Arr变量时。否则,通过使用该函数,您可以获得与使用数组构造函数的代码相同的效果(填充临时变量,分配)。甚至使该函数内联也无济于事,因为 Delphi 不对托管类型进行返回值优化。 -
@StefanGlienke:问题中的测试代码会产生这些不同的结果,试试吧(我使用的是 Delphi XE7)。
-
我做了,由于我解释的原因,它产生了类似的结果。
标签: arrays delphi dynamic-arrays delphi-xe7