3

電卓を作成する必要があり、その最初の関数が 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;

デビッドが答えを出したので、私は数学について質問しました.2つの方程式を導き出し、両方の方法で特定の階乗がコンピューターに費やす時間を決定するのに役立ちます.

4

3 に答える 3

8

非常に低い解像度のタイマーを使用しており、階乗関数の単一の評価は速すぎて登録することさえできません。

より高い解像度のタイマーを使用することもできますが、はるかに簡単な方法は、時間がかかるものの時間を計ることです。factorial への 1 回の呼び出しのタイミングを計る代わりに、1000 または 100 万の時間を計ります。

整数入力に対して高速階乗関数を実装することに実際に関心がある場合は、ルックアップ テーブルを使用する必要があります。

価値があるのは、診断ユニットの TStopWatch の方が、日付/時刻関数よりもタイミングに便利だと思います。

于 2013-02-09T08:10:21.630 に答える
5

プロファイラーを使用します。Delphi の最近のバージョンには、AQTimeprofiler Delphiの機能が制限されたバージョンが含まれていますが、ここで検索すると、StackOverflowで Delphi 用のプロファイラーとメモリ分析ツールが見つかります。

プロファイラーを使用すると、さまざまな部分の実行に費やされた正確な時間を含む、いくつかの異なる方法でコードを評価できます。結果を使用して、どちらがより長い (またはより短い) 時間がかかるかを判断できます。

于 2013-02-09T02:50:26.983 に答える
0

テストのためだけの場合は、ループの前と後にGetTime()の代わりにTimeGetTime()を配置できますか。次に、値をリストボックスに保存して、所要時間を確認します。

それが遅すぎる場合は、QueryPerformanceCounter/QueryPerformanceFrequencyを試してください

于 2013-02-10T04:11:57.270 に答える