作为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在每次循环迭代中直接调用列表项,我想知道它是否添加到堆中并在每次循环迭代时都释放。另一方面,第二种情况显然是通过简单地声明一个局部变量来分配一个堆。
我想知道哪种方案在堆分配上执行较重的负载(这是导致性能问题的主要原因之一)?
最佳答案
现在,我很好奇的是在两种情况下堆分配如何工作。
您的示例中没有堆分配(除非DoSomething()
在内部分配内存)。
方案1在每次循环迭代中直接调用列表项
方案2也是如此。
我想知道它是否添加到堆中并在每次循环迭代时都释放。
什么都没有添加到堆中。
另一方面,第二种情况显然是通过简单地声明一个局部变量来分配一个堆。
局部变量分配在堆栈上,而不是堆上。但是,变量可以指向堆上的内存。方案2中的S
变量可以,因为TObject
派生的类始终分配在堆上。 S
只是堆栈上的局部变量,它指向TSomething
对象占用的堆内存。
我想知道哪种方案在堆分配上执行较重的负载(这是导致性能问题的主要原因之一)?
两者都不是,因为您的示例中没有堆分配。
关于delphi - 在堆分配中哪种情况更轻/更重?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32107543/