作为a previous answer to another question的后续行动,我对堆分配在循环中的工作方式感到好奇。
举例说明以下两种情况:
声明:
SomeList: TObjectList<TSomething>;
情景1:
begin
for X := 1 to 10 do
SomeList[X].DoSomething;
end;
情景2:
var
S: TSomething;
begin
for X:= 1 to 10 do begin
S:= SomeList[X];
S.DoSomething;
end;
end;
现在我很好奇的是堆分配在两种情况下的工作原理。场景1在每次循环迭代中直接调用列表项,我想知道它是否每次循环迭代时都会添加到堆和释放。另一方面,第二种情况显然只有一个堆分配,只需声明一个局部变量。
我想知道哪种情况会对堆分配造成更大的负担(导致性能问题的主要原因之一)?
答案 0 :(得分:6)
现在我感到好奇的是堆分配在两种情况下的工作方式。
您的示例中没有堆分配(除非DoSomething()
在内部分配内存)。
场景1直接调用每个循环迭代中的列表项
情景2也是如此。
我想知道它是否会在每次循环迭代时添加到堆和释放。
没有任何东西被添加到堆中。
另一方面,第二种情况显然只有一个堆分配,只需声明一个局部变量。
局部变量分配在堆栈上,而不是堆上。但是,变量可以指向在堆上的内存中。方案2中的S
变量确实存在,因为TObject
- 派生类总是在堆上分配。 S
只是堆栈上的一个局部变量,它指向TSomething
对象占用的堆内存。
我想知道哪种情况会对堆分配造成更大的负担(导致性能问题的主要原因之一)?
两者都没有,因为您的示例中没有堆分配。