作为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/

10-11 23:00
查看更多