【问题标题】:How can I measure the difference of speed of code between loop and recursive method?如何测量循环和递归方法之间代码速度的差异?
【发布时间】:2013-01-24 22:00:22
【问题描述】:

假设我们要创建一个计算器,它的第一个函数是 Fatorial。 我们可以将其编写为递归函数或使用循环来获取结果。 我们都知道递归更慢,因为它是指数性质的。 但是如何通过代码而不是通过行数来证明呢?

我试图计算花费的毫秒数,但对于我的 i7,它在初始时间和代码停止之间始终为零。

如何衡量循环和递归方法的代码速度差异?

type
  TJanela = class(TForm)
    Instrucao: TLabel;
    Entrada: TEdit;
    Botao: TButton;
    procedure Calcular(Sender: TObject);
  end;

var
  Janela: TJanela;
  Val, Fat, Start, TimeRecursive, TimeLoop: Int64;

function FR(N: Int64): Int64; // Fatorial Recursivo
function FL(N: Int64): Int64; // Fatorial em Loop

implementation

{$R *.dfm}

procedure TJanela.Calcular(Sender: TObject);
begin
  Val := StrToInt(Entrada.Text);
  Start := StrToInt(FormatDateTime('nnsszzz',Now));
  Fat := FR(Valor);
  TimeRecursive := StrToInt(FormatDateTime('nnsszzz',Now)) - Start;
  Start := StrToInt(FormatDateTime('nnsszzz',Now));
  Fat := FL(Valor);
  TimeLoop := StrToInt(FormatDateTime('nnsszzz',Now)) - Start;
  if Val > 25 then
    ShowMessage('Delphi can't calculate above [ 25! ]')
  else
    ShowMessage(' [ ' +
                IntToStr(Val) + '! ] is equal to [ ' +
                FormatFloat('###,###,###,###,###,###',Fat) + ' ]'#13#13+
                'Recursive: [ ' + IntToStr(TimeRecursive) + ' ] ms;'#13+
                'Loop: [ ' + IntToStr(TimeLoop) + ' ] ms;');
end;

function FR(N: Int64): Int64;
begin
  if N <= 1 then
    Result := 1
  else
    Result := N * FR(N - 1);
end;

function FL(N: Int64): Int64;
var
  I: Integer;
begin
  for I := 2 to N - 1 do
    N := N * I;
  if N = 0 then
    Result := 1
  else
    Result := N;
end;

既然 David 给出了答案,我在 Mathematics 上提出了一个问题,以便他们可以帮助我得出两个方程式,以确定给定阶乘在两种方法中在计算机上花费的近似时间。

【问题讨论】:

标签: performance delphi loops recursion


【解决方案1】:

使用profiler。 Delphi 的最新版本包括有限功能版本的 AQTime,但在此处搜索 profiler Delphi 会在 StackOverflow 上找到 Profiler and Memory Analysis Tools for Delphi

分析器允许您以几种不同的方式评估您的代码,包括执行代码各个部分所花费的精确时间。您可以使用结果来确定哪个需要更多(或更少)时间。

【讨论】:

  • 注意:已知 AQTime 会导致 Delphi XE2 Update 4 中的 IDE 出现异常问题 - 存在随机破坏代码完成功能的问题。参考我的一个问题:stackoverflow.com/questions/10037719/…
  • 另外,codesite 的设置也非常简单,并且会为您提供时间工具
  • 如果你使用分析器,你需要非常小心,分析的行为不会改变在分析器下运行代码所花费的时间。
【解决方案2】:

您正在使用分辨率很低的计时器,并且对阶乘函数的单次评估太快,甚至无法注册。

您可以使用更高分辨率的计时器,但到目前为止,最简单的方法是对需要更长时间的事情进行计时。而不是计时一次调用阶乘,计时一千或一百万。

如果您真的对实现快速阶乘函数感兴趣,对于整数输入,您应该使用查找表。

对于它的价值,我认为诊断单元中的 TStopWatch 比日期/时间功能更方便计时。

【讨论】:

  • 有效!我在“Factorial(N)”之前添加了“for I := 1 to 1000000 do”,结果是递归方法为 145ms,循环方法为 81ms。谢谢!
  • 尝试查找表。应该会快很多。
  • 在循环方法中,我得到了 0 中的 3 毫秒! 20 人中有 84 人!在递归方法中,我在 0 中得到了 3 毫秒! 20 秒后 145 毫秒!
  • 现在我正在尝试提出一个方程式来记录超出范围的结果。
  • 我不明白你想用这些 cmets 表达什么观点。
【解决方案3】:

如果它只是为了测试,你可以在循环之前和之后放置一个 TimeGetTime() 而不是 GetTime()。然后只需将值保存在列表框中即可查看需要多长时间。

如果速度太慢,请尝试 QueryPerformanceCounter/QueryPerformanceFrequency

【讨论】:

    猜你喜欢
    • 2020-07-24
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 2013-09-10
    • 2017-10-10
    相关资源
    最近更新 更多