Rのタイミング関数[終了]


36
  1. 関数の実行を繰り返すのにかかる時間を測定したいと思います。あるreplicate()と同等のループに使用して?例えば:

    system.time(replicate(1000, f()));
    system.time(for(i in 1:1000){f()});

    どちらが好ましい方法です。

  2. の出力でsystem.time()sys+user、プログラムを実行するための実際のCPU時間ですか?あるelapsed番組の時間性能の良い測定?


3
記録のためだけに、この質問の流れを変えるには明らかに遅すぎるので、これはStackOverflowに最も適していると思う種類の問題です。
マットパーカー

2
@Matt私は、プログラムがSOにどれほど適しているかという質問に同意します。また、この質問の文字通りの解釈(いくつかの回答で取られている)がCVのトピックから外れていることに同意します。ただし、タイミング実験の設計とそのような実験の結果の分析には、統計的な関心があるようです。
whuber

回答:


19

プログラムの効果的なタイミング、特に代替ソリューションの比較に関心がある場合、コントロールが必要です!良い方法は、計時しているプロシージャを関数に入れることです。タイミングループ内で関数を呼び出します。基本的に、関数からすべてのコードを取り除き、そこから戻るだけで、スタブプロシージャを記述します(ただし、すべての引数は残します)。スタブをタイミングループに入れてリタイムします。これは、タイミングに関連するすべてのオーバーヘッドを測定します。手順時間からスタブ時間を減算してネットを取得します。これは、実際に必要な時間の正確な測定値である必要があります。

最近のほとんどのシステムは、永久に中断される可能性があるため、複数のタイミングを実行して変動をチェックすることが重要です。秒の長い実行を1回実行する代わりに、それぞれ約N / m秒のm回の実行を実行します。これをダブルループで一度に実行すると便利です。処理が簡単であるだけでなく、各時系列に少し負の相関関係が導入され、実際に推定値が改善されます。NmN/m

これらの実験的設計の基本原則を使用することにより、コードのデプロイ方法による違い(forループとreplicate()の違いなど)を本質的に制御できます。それはあなたの問題を解決します。


25

あなたの2つの点について:

  1. 文体的です。replicate()機能しているので気に入っています。
  2. 私はelapsed、3番目の数値に注目する傾向があります。

私がよくやることは

N <- someNumber
mean(replicate( N, system.time( f(...) )[3], trimmed=0.05) )

呼び出しのN回の繰り返しの90%のトリム平均を取得しf()ます。

(編集、思考をとってくれたHadleyに感謝します。)


2
じゃないmean(replicate(N, system.time(f(...))[3]), trim = 0.05)
ハドリー

2
f()呼び出しが長い場合は問題ありません。ただし、f()呼び出しが短い場合、タイミング呼び出しのオーバーヘッドによりエラー測定値が増加する可能性があります。system.time()をf()を何度も繰り返して1回呼び出すと、エラーが無限値になるまで呼び出しを分割できます(そして、より速く戻ります)。
ジョン

@ジョン:ありがとうございます。しかし、私はあなたの言ったことがよくわかりません。system.time()の内部または外部でf()を繰り返して、どちらが良いか疑問に思っていますか?
ティム

system.time()コマンドを呼び出すたびに、呼び出しに時間がかかり、測定エラーが発生します。これは少量です。しかし、f()が非常に短い呼び出しである場合はどうでしょうか?このエラーは、f()の呼び出しにかかった時間と混同される可能性があります。したがって、単一のsystem.time()呼び出し内でf()を1e5回呼び出すと、エラーは1e5チャンクに分割されます。すべてのf()に対してsystem.time()を呼び出すとき、f()の時間が短い場合に影響があります。もちろん、必要なのが相対的なタイミングだけであれば、それほど重要ではありません。
ジョン

ああ、2番目の部分は、system.call()を1回呼び出すだけの方が速いということです。
ジョン

10

によって返されるタイムステップで時間を計測することもできSys.timeます。これはもちろんウォールタイムを測定するため、リアルタイムの計算時間です。サンプルコード:

Sys.time()->start;
replicate(N,doMeasuredComputation());
print(Sys.time()-start);


1

彼らは異なることをします。あなたがしたいことを時間を計ってください。replicate()は、関数の各実行の結果のベクトルを返します。forループにはありません。したがって、これらは同等のステートメントではありません。

さらに、あなたが何かをしたいいくつかの方法を時間します。次に、最も効率的な方法を見つけることができます。


mod-tip:2番目の部分をDirkの回答へのコメントとして投稿します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.