[教程]QProfile教程之三:分析一个函数中多个代码段的性能影响

一般情况下,我们都是基于函数来分析代码的调用关系和性能,但通过对变量作用域的控制,我们实际上是可以很容易就可以对一个函数的的不同段进行性能计数和分析。

对于一个函数,如果我们要分多段进行分析,可以通过两种方法来处理:

1、通过 begin/end 复合语句,自动控制变量的作用域。我们已知:

  • TQProfile.Calc 是有一个返回值的,我们是通过控制编译器自动维护的返回值生命周期,来记录函数的调用顺序。每一次 Calc 都会入栈一个新的栈信息,并增加引用计数,而每次减少引用计数,都会对应一个栈记录检查,并在正确的时机出栈。
  • 复合语句段中的临时变量的生命周期,仅限于复合语句段。编译器会在对应的 end 语句前,插入清理的代码。

基于以上原因,我们就可以写出类似如下的代码逻辑

begin
  TQProfile.Calc('Phase1');
  ...
  if x>100 then
  begin
    TQProfile.Calc('Phase2');
    ...
  end
  else
  begin
    TQProfile.Calc('Phase3');
    ...
  end;
end;

通过上面的方式,我们就可以得出 Phase1 的总执行时间信息和 Phase2、Phase3 的分段执行时间信息,以及生成 Phase1 对应 Phase2、Phase3 的阶段调用信息。

2、通过变量手动控制作用域。我们已知:

  • TQProfile.Calc 返回一个 TQProfileCalcResult 的记录值 ,其中的 Counter 指向引用计数,我们只需要将它赋值为空,就可以减少引用计数。

基于上述知识点,我们可以写出下面的代码:

var
  P1,P2,P3:TQProfileCalcResult;
begin
  P1:=TQProfile.Calc('Phase1');
  ...
  if x>100 then
  begin
    P2:=TQProfile.Calc('Phase2');
    ...
    P2.Counter:=nil;
  end
  else
  begin
    P3:=TQProfile.Calc('Phase3');
    ...
    P3.Counter:=nil;
  end;
  P1.Counter:=nil;
end;

其效果与前面的示例代码是等价的,这种控制方式的优点是我们可以按需要缩减衡量的代码段的数据范围。

滚动至顶部