在不使用 `free` 的情况下使用 `TStopWatch`

5
我在Delphi 10.2 Tokyo中使用TStopWatch进行高精度计时。以下是来自https://www.thoughtco.com/accurately-measure-elapsed-time-1058453网站的示例:
 var
  sw : TStopWatch;
  elapsedMilliseconds : cardinal;
begin
  sw := TStopWatch.Create() ;
  try
    sw.Start;
    //TimeOutThisFunction()
    sw.Stop;
    elapsedMilliseconds := sw.ElapsedMilliseconds;
  finally
    sw.Free;
  end;
end;

显然,有一个错误,因为:

  • StopWatch 没有包含 Free
  • Delphi 文档明确说明:

TStopwatch 不是一个类,但仍需要显式初始化[使用 StartNewCreate 方法]。

这很令人困惑。我在一个函数中使用了 TStopWatch,并且没有使用 free。这个函数可能在每个会话期间被调用多次(根据用法可能会有数百次)。这意味着将创建多个 TStopWatch 实例,而不被释放。

是否存在内存泄漏或其他复杂情况的可能性?如果答案是肯定的,那我该怎么办?我必须为每个应用程序创建只有一个实例的 TStopWatch 吗?还是应该使用其他函数?或者其他方法?


1
TStopWatch.CreateTStopWatch.StartNew之间的重要区别在于前者创建了一个停止状态的秒表,而后者创建了一个启动状态的秒表。两者都有各自的用途,例如在循环中以startstop命令包围的行的重复累积计时时,使用TStopWatch.Create进行准备;其他人已经提供了使用StartNew的用例。阅读文档是值得的。 - Tom Brunberg
1
你的问题在于混淆了链接文章中的TStopwatch和Delphi自带的那个。前者是一个类,后者是一个带有方法的记录。后者不需要析构函数或Free,并且每次调用Create不会生成新的秒表。 - Rudy Velthuis
@TomBrunberg,我不知道你的评论被错过了,但是它解释了很多问题。我犯了一个错误,用TStopWatch.StartNew 替换了 TStopWatch.Create。现在,我明白我应该使用前者。感谢您提供的信息。 - blackcanopus
1个回答

11

这个链接示例是基于类的TStopWatch

unit StopWatch;
interface
uses 
  Windows, SysUtils, DateUtils;

type 
  TStopWatch = class
  ...

在Delphi引入基于记录(record)的TStopWatch之前,它已经被发布。

由于类变量需要在使用后调用Free,而基于记录的不需要,在这里就没有混淆。

可以继续使用Delphi基于记录的TStopWatch,无需在使用后释放它。

通常我使用以下模式:

var
  sw : TStopWatch;
begin
  sw := TStopWatch.StartNew;
  ... // Do something
  sw.Stop;
  // Read the timing
  WriteLn(sw.ElapsedMilliseconds);  

谢谢澄清。我该如何处理记录变量?使用create而不使用free可以吗? - blackcanopus
看我的更新。你根本不需要 Create。它只是一个记录类函数。 - LU RD
@blackcanopus:使用 SW.StartNew ... SW.ElapsedMilliseconds ... SW.Stop 模式是在 System.Diagnostics 中使用 TStopwatch 的通常模式。无需 Create,但通常应调用 StartNew - Rudy Velthuis
LU RD和@Rudy,Create也有很好的理由,可以看看我对OP的评论。 - Tom Brunberg
@Tom:我总是使用 StartNew...Stop 的顺序。效果很好。 - Rudy Velthuis
@Rudy,我没说不行。你愿意就继续吧 ;) - Tom Brunberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接